1.概念
Broadcast是一种广泛运用的在应用程序之间传输信息的机制。而BroadcastReceiver 是对发送出来的Broadcast 进行过滤接受并响应的一类组件,是Android四大组件之一
1.Android 为了将系统运行时的各种“事件”通知给其他应用
2.假如我们开发在线播放视频类的APP,那么我们就有必要监听网络转态改变的事件广播
3.如果用户的网络状态从wifi改变为了4G上网,那么应该提示用户是否使用4G网络继续播放视频
4.如果不提示用户,那么就可能导致用户流量被大量使用,一会儿功夫,用户可能就要停机了
BroadcastReceiver
1.广播接收者(BroadcastReceiver)用于接收广播,广播的发送是通过调用sendBroadcast(Intent)/sendOrderedBroadcast(Intent)来实现的
2.通常一个广播可以被多个广播接收者所接收
2.基本类型
广播被分为两种不同的类型:“普通广播/无序广播(Normal Broadcasts)”和“有序广播(OrderedBroadcasts)”
无序广播
1.不会被某个广播接收者终止
2.可以在同一时刻(逻辑上)被所有接收者接收到
3.消息传递的效率比较高
4.接收者不能将处理结果传递给下一个接收者,并且无法终止广播的传播
有序广播
1.按照接收者声明的优先级别依次接收广播
2.在传递的过程中如果有某个接收者终止(abortBroadCast)了该广播,那么后面的接收者就接收不到该广播
广播接收者要在AndroidManifest.xml中进行注册
1.优先级别声明在intent-filter 元素的android:priority 属性中
2.数越大优先级别越高,取值范围:-1000 到1000
3.优先级别也可以调用IntentFilter 对象的setPriority()进行设置
3.Code
1.无序广播
- 发送无序广播
//定义一个意图
Intent intent = new Intent();
//设置意图action
intent.setAction("com.ccav.news");
//绑定数据
intent.putExtra("data", "我是无序广播的数据");
//发送无序广播
sendBroadcast(intent);
- 接收无序广播
//编写自定义BroadCastReceiver
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("哈哈哈,接收到了无序广播");
System.out.println(intent.getStringExtra("data"));
}
}
- 配置清单文件
<receiver android:name="com.demo.MyReceiver">
<intent-filter >
<action android:name="com.ccav.news"/>
</intent-filter>
</receiver>
2.有序广播
- 发送有序广播
Intent intent = new Intent();
intent.setAction("com.gov.sendEggs");
/**
* 参数1 Intent 类型:意图
* 参数2 String 类型receiverPermission,接收器需要的权限
* 参数3 BroadcastReceiver 类型,自己定义的接收者作为最终接收者
* 参数4 Handler 类型,用于执行接收器的回调,如果为null 则在主线程中执行
* 参数5 int 类型,结果代码的初始码
* 参数6 初始化参数
* 参数7Bundle 类型,额外的数据
*/
//注意:该广播是直接被new出来作为一个参数传递给sendOrderedBroadcast该方法的,所以不需要在清单文件进行配置
sendOrderedBroadcast(intent, null, new MyReceiver(), null,1,"每人10个茶叶蛋", null);
- 接收有序广播
public class First extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String data = getResultData();
System.out.println("第一个人,收到消息"+data);
setResultData("每人6个茶叶蛋");
}
}
public class Second extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String data = getResultData();
System.out.println("第二个人,收到消息"+data);
setResultData("每人3个茶叶蛋");
}
}
public class Third extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String data = getResultData();
System.out.println("第三个人,收到消息,"+data);
setResultData("有茶叶蛋吃,好开心");
}
}
- 配置清单文件
<receiver android:name="com.demo.First" >
<intent-filter android:priority="1000">
<action android:name="com.gov.sendEggs" />
</intent-filter>
</receiver>
<receiver android:name="com.demo.second" >
<intent-filter android:priority="800">
<action android:name="com.gov.sendEggs" />
</intent-filter>
</receiver>
<receiver android:name="com.demo.Third" >
<intent-filter android:priority="600">
<action android:name="com.gov.sendEggs" />
</intent-filter>
</receiver>
4.特殊的广播接收者—锁屏与解屏
在Android 中一些操作比较频繁的事件,比如锁屏解屏和电量的变化,也会发送特定的广播。此类广播的注册是无法注册在AndroidManifest.xml中,只能在代码中进行注册。
BroadCastReceiver的注册方式有两种:
1.静态注册(就是通过AndroidManifest.xml 注册)
2.动态注册(就是通过代码注册)
3.前面使用到的BroadCastReceiver全部都使用的是静态注册方式,其实也可以使用动态注册
4.对于锁屏解屏和电量变化的监听只能通过动态注册
- 动态注册
//主页面
public class MainActivity extends Activity {
ScreenStatusReceiver receiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
receiver = new ScreenStatusReceiver();
IntentFilter filter = new IntentFilter();
//添加屏幕关闭的action
filter.addAction("android.intent.action.SCREEN_OFF");
//添加屏幕点亮的action
filter.addAction("android.intent.action.SCREEN_ON");
//注册广播接受者
registerReceiver(receiver, filter);
}
@Override
protected void onDestroy() {
// 取消注册广播接受者
unregisterReceiver(receiver);
receiver = null;
super.onDestroy();
}
}
//自定义类继承BroadCastReceiver 类
public class ScreenStatusReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Log.d("tag", "监听到屏幕点亮了");
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
Log.d("tag", "监听到屏幕关闭了");
}
}
}
细节要点
1.监听锁屏和解屏不需要额外的权限,因此可以直击运行
2.应用退出了,会调用onDestory()方法,继而调用unregisterReceiver(receiver)方法,那么就无法监听到该广播
3.销毁Activity时缺少unregisterReceiver()会导致IntentReceiver的泄露
4.必须保证Activity 销毁前将接收者给反注册掉