android四大组件之BroadcastReceiver总结

1,定义:

广播是一个全局的监听器,分为发送广播和接收广播两部分。

2,应用场景:

1,android不同组件和不同模块内通信(多线程与多进程);

2,不同app之间的组件之间消息通信;

3,Android系统在特定情况下与App之间的消息通信。

3,实现原理:

广播使用了设计模式中的观察者模式,基于消息的发布和订阅模型,将广播的发送和接收进行了解耦。模型中有三个角色,分别是 :消息订阅者(广播接收),消息发送者(广播发布),消息处理中心(AMS Activity Manager Service)。广播实现原理描述如下:

1,广播发送者通过Binder机制向AMS发送广播;(发送与接收为异步过程,所以发送者不会care有无接收者或者何时收到)

2,广播接收者通过Binder机制在AMS中注册;

3,AMS根据广播发送者的要求,在AMS的注册表中寻找广播接受者,寻找依据是IntentFilter,Permisssion,AMS将广播发送到相对应的消息循环队列中;

4,接收者通过消息循环拿到广播,并回调onReceive方法。

4,广播注册类型:

BroadcastReceiver总体上可以分为两种注册类型:静态注册和动态注册。

4.1静态注册

直接在AndroidManifest.xml文件中进行注册。可以在程序未启动的情况下接收到广播,规则如下:

<receiver android:enabled=["true" | "false"]  
android:exported=["true" | "false"]   //此broadcastReceiver能否接收其他App的发出的广播,默认值是由receiver中有无intent-filter决定的:如果有intent-filter,默认值为true,否则为false
android:icon="drawable resource"
android:label="string resource"
android:name="string"
android:permission="string"
android:process="string" >
<intent-filter>    //设置接收广播的类型
  <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
    </intent-filter>
</receiver>

4.2动态注册:

//一般在Activity的onResume方法中进行动态注册广播(防止内存泄漏)
mBroadcastReceiver = new MyBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BROADCAST_ACTION);
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
registerReceiver(mBroadcastReceiver, intentFilter);

在onPause方法中取消动态网络变化广播接收器的注册  (防止内存泄漏)
unregisterReceiver(mBroadcastReceiver);

//自定义接受网络变化的广播接收器
    class MyBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
           //todo
           // 接收到广播后,会自动回调onReceive方法,intent是广播发送过来的意图,可以传递参数等等;
          // 默认情况下,广播接收者运行在UI线程,不能执行耗时操作,否则将阻塞UI线程,导致ANR
          // 一般涉及到与其他组件之间的交互,如Notification,启动Activity等等。
            }
        }
    }

4.3 两种注册方式的区别

1,静态注册在Manifest中进行,不受任何组件的生命周期的影响,能够随时接收到广播,应用于需要随时监听的功能,但这样也就更加的耗电,占内存。

2,在其他组件中动态注册,跟随组件的生命周期而变化,相比静态更加灵活。

5,广播分类

5.1,标准广播

Intent intent = new Intent();
intent.setAction(BROADCAST_ACTION);  //广播注册了此action的就会收到此广播
//发送广播
sendBroadcast(intent);

5.2,有序广播 

1,发送出去的广播被接收是按照先后顺序处理。 按照Priority的属性值从大到小排序。Priority相同时,动态广播优先。

2,优先接到广播的接收者可以对广播进行拦截或者对广播进行修改。

3,有序广播发送用sendOrderedBroadcast(intent, null); 

5.3,本地广播

其他App可能会针对性的发出与当前App intent-filter相匹配的广播,由此导致当前App不断接收到广播并处理;其他App可以注册与当前App一致的intent-filter用于接收广播,获取广播具体信息。无论哪种情形,这些安全隐患都确实是存在的。虽然可以通过控制permission,export等控制,为此,Android v4兼容包中给出了封装好的LocalBroadcastManager类,用于统一处理App应用内的广播问题,使用方式上与通常的全局广播几乎相同,只是注册/取消注册广播接收器和发送广播时将主调context变成了LocalBroadcastManager的单一实例。本地广播的使用用例如下:

//步骤1:实例化LocalBroadcastManager的实例 
localBroadcastManager = LocalBroadcastManager.getInstance(this); 
//步骤2:设置接收广播的类型 intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE); 
//步骤3:调用LocalBroadcastManager单一实例的registerReceiver()方法进行动态注册 localBroadcastManager.registerReceiver(mBroadcastReceiver, intentFilter); 
//步骤4:取消注册应用内广播接收器 localBroadcastManager.unregisterReceiver(mBroadcastReceiver); //发送应用内广播 Intent intent = new Intent(); intent.setAction(BROADCAST_ACTION); localBroadcastManager.sendBroadcast(intent);

5.4 系统广播

Android中内置了多个系统广播:只要涉及到手机的基本操作(如开机、网络状态变化、拍照等等),都会发出相应的广播,使用系统广播时,只需要在注册广播接收者时定义相关的action即可,并不需要手动发送广播,当系统有相关操作时会自动进行系统广播每个广播都有特定的Intent - Filter(包括具体的action),常用的Android系统广播如下:

1:监听网络变化                 android.net.conn.CONNECTIVITY_CHANGE

2:关闭或打开飞行模式       Intent.ACTION_AIRPLANE_MODE_CHANGED

3,电池电量低                      Intent.ACTION_BATTERY_LOW

4,屏幕锁屏                          Intent.ACTION_CLOSE_SYSTEM_DIALOGS

6 特别注意

对于不同注册方式的广播接收器回调OnReceive(Context context,Intent intent)中的context返回值是不一样的:

  • 对于静态注册(全局+应用内广播),回调onReceive(context, intent)中的context返回值是:ReceiverRestrictedContext;
  • 对于全局广播的动态注册,回调onReceive(context, intent)中的context返回值是:Activity Context;
  • 对于应用内广播的动态注册(LocalBroadcastManager方式),回调onReceive(context, intent)中的context返回值是:Application Context。
  • 对于应用内广播的动态注册(非LocalBroadcastManager方式),回调onReceive(context, intent)中的context返回值是:Activity Context;

 

猜你喜欢

转载自blog.csdn.net/weixin_42042620/article/details/85263429