组件——BroadcastReceiver

作者: 四喜汤圆 | 来源:发表于2019-07-07 18:57 被阅读0次

本篇是对Android四大组件:BroadcastReceiver史上最全面解析的学习笔记。

一、作用

广播接收器的作用是接收应用/Andorid系统内的广播,并且做出相应反应。

二、相关概念

1. 观察者模式

...待续

三、 具体使用

1. 自定义广播接收器

创建一个类,继承自BroadcastReceiver,重写onReceive(),当接收当广播后回调该方法。

public class MyReceiver extends BroadcastReceiver{
    @Override
    public void onReceive(Context context, Intent intent) {
        // do something
    }
}

2. 注册广播接收器

(1)静态注册
AndroidManifest.xml中,使用<receiver>标签实现静态注册。

<receiver android:name=".MyReceiver"
            android:enabled="true"
            android:exported="true"
            android:icon="@android:color/background_dark"
            android:label="@string/app_name"
            android:permission="@string/app_name"
            android:process="@string/app_name">
    <intent-filter android:priority="100">
        <action android:name="android.net.conn.CONNECTIVITY_CHANGED"/>
    </intent-filter>
</receiver>
  • android:enable
    是否启用这个广播接收器

  • android:exported
    Android 四大组件都有这个属性。是否允许这个广播接收器接收本程序以外的广播。

  • iconlablename
    基本属性配置

  • intent-filter
    每个 receiver 都要配置过滤条件,action表示该广播接收器感兴趣的广播,否则什么广播都接收不到。

(2)动态注册
在代码中调用Context.registerReceiver()

动态注册要有对应的注销。注册一般放在生命周期的onResume()中,注销放在onPause()中。因为当系统内存不足或其他情况下,需要回收 Activity 时,onPause()一定会被回调,但onStop()onDestroy()不一定会有机会被回调。这样保证了广播接收器一定会被注销,防止内存泄露。

public class MainActivity extends AppCompatActivity {

    MyReceiver receiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }

    @Override
    protected void onResume() {
        super.onResume();
        receiver = new MyReceiver();
        // 广播接收器要设置相应的 action,否则接收不到任何广播
        IntentFilter filter = new IntentFilter();
        // 设置可接收的广播类型
        filter.addAction(android.net.conn.CONNECTIVTY_CHANGED);
        // 注册广播接收器
        registerReceiver(receiver, filter);
    }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(receiver);
    }
}

3. 发布广播

(1)普通广播
开发者自定义的广播。把意图发送出去,即是发送广播。

Intent intent = new Intent();
intent.setAction("BROADCAST");
sendBroadcast(intent);

若广播接收器的 action 中指定接收名为BROADCAST"的广播,则可以接收到。

(2)系统广播

  • Android 内置了多个系统广播:只要涉及到手机的基本操作(如开机、网络状态变化、拍照等),都会发出相应广播。

  • 每个广播都有特定的Intent - Filter(包括具体的action)

例如:接收开机广播android.intent.action.BOOT_COMPLETED,需要权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

(3)粘性广播
用的比较少。

(4)有序广播

sendOrderedBroadcast(intent);
  • 发出去的广播被广播接收者按先后顺序接收

  • 广播接收者接收的顺序根据<receiver>标签中的android:priority属性的顺序确定

priority的值越大越靠前;

priority的值相同,则动态注册的广播优先。

  • 先接收广播的 Receiver 可以截断广播,则后面的 Receiver 接收不到

  • 先接收广播的 Receiver 可以修改广播,则后面的 Receiver 接收到修改后的广播

(5)应用内广播
Android 中的广播可以跨 App 直接通信,那么可能出现的问题有:

  • 其他 App 有针对性地发送与本 App 的Intent-filter相匹配的广播,使得本 Application 不断接收广播并做出处理,消耗资源

  • 其他 App 注册与本 App 相同的Intent-filter的 Receiver,用于接收本 App 的广播,存在安全问题

所以将全局广播修改为局部广播,有2种方法。

a)将全局广播设置为局部广播

  • 注册广播时将exported属性设置为false,使得非本App内部发出的此广播不被接收;

  • 在广播发送和接收时,增设相应权限permission,用于权限验证;

  • 发送广播时指定该广播接收器所在的包名,此广播将只会发送到此包中的App内与之相匹配的有效广播接收器中

b)使用封装好的LocalBroadcastManager类
LocalBroadcastManager 发送的应用内广播的 Receiver 只能通过动态方式注册。

LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);

receiver = new MyReceiver();
// 广播接收器要设置相应的 action,否则接收不到任何广播
IntentFilter filter = new IntentFilter();
// 设置可接收的广播类型
filter.addAction(android.net.conn.CONNECTIVTY_CHANGED);
// 注册广播接收器
localBroadcastManager.registerReceiver(receiver, filter);

localBroadcastManager.unregisterReceiver(receiver);

4. 接收广播

广播接收器接收到广播后会回调onReceive()方法。

四、注意事项

对于不同注册方式的广播接收器回调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;

相关文章

网友评论

    本文标题:组件——BroadcastReceiver

    本文链接:https://www.haomeiwen.com/subject/quwrhctx.html