BroadcastReceiver

BroadcastReceiver

继承BroadcastReceiver来创建一个广播接收器。

public class MyReceiver extends BroadcastReceiver {
    
    public static final String ACTION = "com.daking.app.broadcast.MyReceiver";
    
    @Override
    public void onReceive(Context context, Intent intent) {
        // 处理广播
    }
}
1
2
3
4
5
6
7
8
9

BroadcastReceiver注册方式

BroadcastReceiver有两种注册方式:静态注册和动态注册。

静态注册

在AndroidManifest.xml中使用<receiver>标签来静态注册BroadcastReceiver。

<receiver
    android:name=".receiver.MyReceiver"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
        <action android:name="com.daking.app.broadcast.MyReceiver"/>
    </intent-filter>
</receiver>
1
2
3
4
5
6
7
8

静态注册的BroadcastReceiver可在Android程序未启动的情况下监听到广播。

动态注册

使用Context#registerReceiver()来动态注册BroadcastReceiver。

MyReceiver myReceiver = new MyReceiver();
context.registerReceiver(myReceiver, new IntentFilter(MyReceiver.ACTION));
1
2

使用Context#unregisterReceiver()来动态注销BroadcastReceiver。

context.unregisterReceiver(myReceiver);
1

动态注册的BroadcastReceiver必须要Android程序已启动,而且调用代码进行注册后,方可监听到广播。

动态注册的BroadcastReceiver切记要在不再使用时进行注销。一般在Activity的onCreate方法中动态注册,在其onDestroy方法中进行注销。

发送广播

发送标准广播

使用Context#sendBroadcast(Intent)来发送一个标准广播。

标准广播是异步执行的广播。广播发出后,所有BroadcastReceiver几乎会在同一时刻收到。

发送有序广播

使用Context#sendOrderedBroadcast(Intent)来发送一个有序广播。

有序广播是同步执行的广播。广播发出后,同一时间只有一个BroadcastReceiver能收到,当它处理完后,下一个BroadcastReceiver才能收到此广播。

在AndroidManifest.xml中对应的<receiver>上使用android:priority属性来设置BroadcastReceiver的优先级,值越大则优先级越高,越先收到广播。

可在BroadcastReceiver中调用abortBroadcast()来截断广播,之后的BroadcastReceiver就不会接收到此广播。

BroadcastReceiver生命周期

静态注册的BroadcastReceiver

静态注册的BroadcastReceiver,每收到一个广播,都会创建一个新的BroadcastReceiver对象。

该BroadcastReceiver对象只会在其onReceive(Context, Intent)方法被调用的期间有效,一旦onReceive方法执行完并返回值,该对象就变成不活跃的,而且会在任意时间段内被系统销毁。

该BroadcastReceiver对象的onReceive方法是在主线程中执行的,不能进行耗时操作。也不建议在此方法中开启子线程,因为静态注册的BroadcastReceiver对象的生命周期很短。

动态注册的BroadcastReceiver

动态注册的BroadcastReceiver,每收到一个广播,都会调用Context#registerReceiver()传入的BroadcastReceiver对象的onReceive方法。

该BroadcastReceiver对象需要通过Context#unregisterReceiver()来注销。为了防止泄露,在注册它的Activity等组件销毁时,必须对它进行注销。

该BroadcastReceiver对象的onReceive方法执行在调用Context#registerReceiver()的线程环境中。

广播的权限限制

在讨论广播的权限限制问题时,将发送广播的Android应用称为发送方,而接收广播的Android应用称为接收方

限制接收方

限制接收方的原理是:广播中携带一个自定义的权限声明,只有添加了该权限的Android应用才能接收此广播。

首先,在发送方的AndroidManifest.xml中声明一个自定义的权限,用于表明接收方所需的权限。

<permission android:name="com.daking.broadcast.permission.MY_RECEIVE_PERMISSION"/>
1

接着,发送方在发送广播时要携带上面的自定义权限。

最后,在接收方的AndroidManifest.xml中添加对应的自定义权限声明。

<users-permission
    android:name="com.daking.broadcast.permission.MY_RECEIVE_PERMISSION"/>
1
2

限制发送方

限制发送方的原理是:在<receiver>中添加一个自定义的广播发送权限,只有添加该权限的Android应用才能给该BroadcastReceiver发送广播。

首先,在接收方的AndroidManifest.xml中声明一个自定义的权限,用于表明发送方所需的权限。

<permission android:name="com.daking.broadcast.permission.MY_SEND_PERMISSION"/>
1

接着,在接收方的AndroidManifest.xml中为需要保护的<receiver>使用android:permission添加所需的自定义权限声明。

<receiver 
    android:name=".XXXReceiver"
    android:permission="com.daking.broadcast.permission.MY_SEND_PERMISSION">
1
2
3

最后,在发送方的AndroidManifest.xml中添加对应的自定义权限声明。

<users-permission
    android:name="com.daking.broadcast.permission.MY_SEND_PERMISSION"/>
1
2