BroadcastReceiver(广播接收器)是Android中的四大组件之一,它是一种广泛运用在应用程序之间传输信息的机制。你的应用可以使用它对外部事件进行过滤只对感兴趣的事件进行接收并做出响应。
-
广播接收器是一个专注于接收广播通知信息,并做出对应处理的组件。很多广播是源自于系统代码的──比如,通知时区改变、电池电量低、拍摄了一张照片或者用户改变了语言选项。应用程序也可以进行广播──比如说,通知其它应用程序一些数据下载完成并处于可用状态。
-
应用程序可以拥有任意数量的广播接收器以对所有它感兴趣的通知信息予以响应。所有的接收器均继承自BroadcastReceiver基类。
-
广播接收器没有用户界面。然而,它们可以启动一个activity来响应它们收到的信息,或者用NotificationManager来通知用户。通知可以用很多种方式来吸引用户的注意力──闪动背灯、震动、播放声音等等。一般来说是在状态栏上放一个持久的图标,用户可以打开它并获取消息。
我们要实现一个广播事件,可以按照一下步骤进行:
-
注册广播事件:写一个继承BroadCastReceiver的类,重写onReceive()方法 ,注册该广播接收者。 注册方式有两种,一种是静态注册,就是在 AndroidManifest.xml 文件中定义:
<receiver android:name=".MyBroadcastReceiver"> <intent-filter> <action android:name="com.android.broadcast.received" /> </intent-filter> </receiver>
一种是动态注册,一般在Activity可交互时onResume()内注册BroadcastReceiver:
动态注册广播接收器还有一个特点,就是当用来注册的Activity关掉后,广播也就失效了。静态注册无需担忧广播接收器是否被关闭,只要设备是开启状态的,广播接收器也是打开着的。也就是说哪怕app本身未启动,该app订阅的广播在触发时也会对它起作用。IntentFilter intentFilter=new IntentFilter(); intentFilter.addAction("com.android.broadcast.received"); registerReceiver(mMyBroadcastReceiver, intentFilter); //注销 unregisterReceiver(mMyBroadcastReceiver);
-
发送广播事件:通过Context.sendBroadcast来发送,由Intent来传递注册时用到的Action。
-
接收广播事件:当发送的广播被接收器监听到后,会调用它的onReceive()方法,并将包含消息的Intent对象传给它。
注意:广播接收器的生命周期只有10秒左右,如果在onReceive()内做超过10秒的事情,就会报ANR。如果需要完成一项比较耗时的工作,应该通过发送 Intent 给 Service,由Service来完成。这里不能使用子线程来解决,因为 BroadcastReceiver的生命周期很短,子线程可能还没有结束BroadcastReceiver就先结束了,BroadcastReceiver一旦结束,此时 BroadcastReceiver的所在进程很容易在系统需要内存时被优先杀死,因为它属于空进程 (没有任何活动组件的进程 ),如果它的宿主进程被杀死,那么正在工作的子线程也会被杀死,所以采用子线程来解决是不可靠的。
下面来看看发送广播的几种方法:
-
sendBroadcast(Intent intent)和sendBroadcast(Intent intent, String receiverPermission),发送普通广播。第一种方法就不多说了,第二中方法就是发送一个带权限的广播,这个权限有两种限制,一种是限制广播的接收者,如果你发送的广播设置了XX权限,那你的接收器也必须有相应的XX权限:
<!--发送程序代码:--> <!--在AndroidManifest.xml中定义一个权限--> <permission android:name="broadcast.permission" /> //发送广播 context.sendBroadcast(intent,"broadcast.permission");
这样你的广播接收器就可以收到设置了broadcast.permission权限的广播了;还有一种是限制广播的发送者,如果我们定义的接收器设置了XX权限,那么我只能收到设置了XX权限的广播:发送程序代码同上,<!--接收程序代码:--> <!--在AndroidManifest.xml中设置“broadcast.permission”权限-->
<uses-permission android:name="broadcast.permission" />
这样只有拥有broadcast.permission权限的发送者才能给你发送广播。<!--接收程序代码: --> <!--在AndroidManifest.xml中设置“broadcast.permission”权限--> <uses-permission android:name="broadcast.permission" /> <receiver android:name=".MyBroadcastReceiver1" android:permission="broadcast.permission"> <intent-filter> <action android:name="com.android.broadcast.received" /> </intent-filter> </receiver>
-
sendOrderedBroadcast(Intent intent,String receiverPermission),发送有序广播,接收者按照优先级顺序接收广播,优先级别在intent-filter中的priority中声明,取值范围-1000到1000之间,值越大,优先级越高。可以终止广播意图的继续传播和篡改内容。
我们程序中定义了两个接收器MyBroadcastReceive1和MyBroadcastReceive2,MyBroadcastReceive2的优先级高于MyBroadcastReceive1,这时我们用sendOrderedBroadcast来发送一条有序广播,那么MyBroadcastReceive2先收到广播。<receiver android:name=".MyBroadcastReceiver1"> <intent-filter android:priority="400"> <action android:name="com.android.broadcast.received" /> </intent-filter> </receiver> <receiver android:name=".MyBroadcastReceiver2"> <intent-filter android:priority="500"> <action android:name="com.android.broadcast.received" /> </intent-filter> </receiver>
-
sendStickyBroadcast(Intent intent),发送异步广播,sendStickyBroadcast发出的最后一个广播会被保留,当有相应的Recevier处于活跃的,会接受并处理该广播,处理完后该广播依然存在,直到你调用removeStickyBroadcast(intent)主动把它去掉,发送异步广播,要<uses-permission android:name="android.permission.BROADCAST_STICKY" />权限 。