- Boastcast(广播)是一种广泛运用的在应用程序之间传输信息的机制。
- BroadcastReceiver(广播接受者)是对发送出来的广播进行过滤并响应的一类组件,它就是用来接收来自系统和应用中的广播。
- 用途:
- 当开机完成后系统会产生一条广播;有些程序会接收此广播而启动程序,这就是“自启动”。
- 当网络状态改变时系统会产生一条广播;一般用于提示用户。
- 当电池电量改变时,系统会产生一条广播;
- 其他。
为什么需要广播?
假如没有广播,那么,很多事情都要自己做,需要自己想办法去获取数据。
有了广播,我们只需等待广播告诉我们信息。
广播的优点:
- 大大减少开发的工作量和开发周期
- 作为应用开发者,只需要掌握 BroadcastReceiver,不需要了解底层实现。
使用方法:发送: - 把信息装入一个 Intent对象(如Action、Category)
- 通过调用相应的方法将 Intent对象以广播方式发送出去:sendBroadcast()、sendOrderBroadcast()、sendStickyBroadcast()
接收:当 Intent 发送以后,所有已经注册的 BroadcastReceiver 会检查注册时的 IntentFilter 是否与发送的 Intent 相匹配,若匹配则就会调用 BroadcastReceiver的 onReceive()方法。所以当我们定义一个 BroadcastReceiver 的时候,都需要实现 onReceive()方法。
注意:BroadcastReceiver需要注册 :静态注册和代码注册 - BroadcastReceiver 生命周期只有十秒左右。
- BroadcastReceiver 里面不能做一些耗时操作(就是因为生命周期短)
- 耗时操作应该通过发送 Intent 给 Service,由Service来完成
- 不能使用子线程。使用子线程不可靠!因为BroadcastReceiver生命周期太短,可能接收都结束了,子线程还没结束。接收器一旦结束了,Receiver所在的进程很容易在需要的时候被杀死,因为此时它是空进程(没有任何活动组件的进程就是空进程),一旦宿主进程被杀掉了,那么正在工作的子进程也会被杀死。
广播的种类:
- 普通广播(Normal broadcasts)
所有监听该广播的广播接收者都可以监听到该广播。 - 有序广播(Ordered broadcasts)
按照接收者的优先级顺序接收广播,优先级别在 intent-filter中的priority中声明,-1000到1000之间,值越大,优先级越高。可以终止广播意图的继续传播。接收者可以篡改内容。 - 异步广播(粘滞性滞留广播)
不能将处理结果传给下一个接收者,无法终止广播。
普通广播的特点:
- 同级别接收,次序随机
- 级别低的后收到广播
- 接收者不能截断广播的继续传播也不能处理广播
- 同级别动态注册高于静态注册(动态注册的优先级别更高)
有序广播特点: - 同级别接收顺序是随机的
- 能截断广播的继续传播,高级别的广播接收器收到该广播后,可以决定是否截断该广播。
- 接收器能截断广播的继续传播,也能处理广播。
- 同级别动态注册高于静态注册。
异步广播的特点
1、之所以又叫“粘滞性广播”,是因为它的广播会一直存在,不像其他广播一用完就会被销毁。所以这里的示例将采取“先发送广播,后注册接收者”,如果接收者还能接收到广播,就能说明异步广播的“粘滞性”。
注意:“粘滞性”是需要在配置文件中添加权限的:
<uses-permission android:name="android.permission.BROADCAST_STICKY"></uses>
2、并且当我们用动态注册时,我们应该在activity的ondestroy方法中销毁,所以动态注册的这些接收者本身,最好定义为全局变量,然后在方法中初始化。
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<Button
android:id="@+id/send1"
android:onClick="doClick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="发送一条普通广播" />
<Button
android:id="@+id/send2"
android:onClick="doClick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/send1"
android:text="发送一条有序广播" />
<Button
android:id="@+id/send3"
android:onClick="doClick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/send2"
android:text="发送一条异步广播" />
</RelativeLayout>
MainActivity.java
import android.app.Activity;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//动态添加优先级较高
// IntentFilter intentfilter = new IntentFilter("BC_One");
// BC2 bc2 = new BC2();
// registerReceiver(bc2, intentfilter);
}
public void doClick(View v){
switch (v.getId()) {
case R.id.send1://发送一条普通广播
Intent intent = new Intent();
intent.putExtra("msg", "这是一条普通广播");
intent.setAction("BC_One");
sendBroadcast(intent);
break;
case R.id.send2://发送一条有序广播
Intent intent2 = new Intent();
intent2.putExtra("msg", "这是一条有序广播");
intent2.setAction("BC_One");
sendOrderedBroadcast(intent2, null);
break;
case R.id.send3://发送一条异步广播
Intent intent3 = new Intent();
intent3.putExtra("msg", "这是一条有序广播");
intent3.setAction("BC_Three");
sendStickyBroadcast(intent3);
IntentFilter intentfilter = new IntentFilter("BC_Three");
BC3 bc3 = new BC3();
registerReceiver(bc3, intentfilter);
break;
}
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
// unregisterReceiver(receiver);
}
}
BC1.java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
public class BC1 extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
String s = intent.getStringExtra("msg");
System.out.println("reveiver1收到消息:"+s);
abortBroadcast();
//顺序处理数据在传送给下一个
// Bundle bundle = new Bundle();
// bundle.putString("test", "广播处理的数据");
// setResultExtras(bundle);
}
}
BC2.java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
public class BC2 extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
String s = intent.getStringExtra("msg");
System.out.println("reveiver2收到消息:"+s);
// abortBroadcast();
Bundle bundle = getResultExtras(true);
String s2 = bundle.getString("test");
System.out.println("得到的处理结果是:"+s2);
}
}
BC3.java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class BC3 extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("收到了异步广播!");
}
}