`
kanwoerzi
  • 浏览: 1639809 次
文章分类
社区版块
存档分类
最新评论

Android的四大组件之二--BroadcastReceiver

 
阅读更多

Base class for code that will receive intents sent by sendBroadcast(). You can either dynamically register an instance of this class withContext.registerReceiver()or statically publish an implementation through the<receiver>tag in yourAndroidManifest.xml.

(大致的意思:BroadcastReceiver是用于接收通过sendBroadcast()发送的intents。可以通过Context.registerReceiver()动态注册一个实例,或者在AndroidManifest.xml中静态注册)

广播接收器只能用于接受广播,对广播的通知做出相应的处理,很多广播是由系统提供的(如电量不足等);

广播接收器同样没有界面,但是他们可以接受到信息后启动activity或者通过notificationManger通知用户(响铃,振动等);

广播分为两类:

Normal broadcasts:(通过sendBroadcast()发送),是完全异步的。全部的BroadcastReceiver时没有规定的顺序的接收的,逻辑上,可以在同一时刻所有接收者接收到。消息传递的效率比较高,但缺点是,接收者不能将处理结果传递给下一个接收者,并且无法终止广播Intent的传播;

Ordered broadcasts :(通过sendOrderBroadcast()发送),广播一次只发送给一个接收者(每次只有一个接收者可以接收,但是不是全部只有一个接收

者);全部的接收者都是有序的,能够传递结果给下一个接收者,或者放弃广播(这样后面的广播接收者都收不到广播)。按照接收者声明的优先级别(声明

intent-filter元素的android:priority属性中,数越大优先级别越高(如果权限值想听则任意顺序),取值范围:-1000到1000。也可以调用IntentFilter对象的

setPriority()进行设置),被接收者依次接收广播。如:A的级别高于B,B的级别高于C,那么,广播先传给A,再传给B,最后传给C。A得到广播后,可以往广播里存

入数据,当广播传给B时,B可以从广播中得到A存入的数据。


There are two major classes of broadcasts that can be received:

Normal broadcasts (sent with Context.sendBroadcast) are completely asynchronous. All receivers of the broadcast are run in an undefined order, often at the same time. This is more efficient, but means that receivers cannot use the result or abort APIs included here.

Ordered broadcasts (sent with Context.sendOrderedBroadcast) are delivered to one receiver at a time. As each receiver executes in turn, it can propagate a result to the next receiver, or it can completely abort the broadcast so that it won't be passed to other receivers. The order receivers run in can be controlled with the android:priority attribute of the matching intent-filter; receivers with the same priority will be run in an arbitrary order.


普通广播:异步,数据不共享,传递效率高

有序广播:同步,数据可以达到共享,传递效率低


注意:

如果onResume()中注册了接收者,则必须在onPause()中注销;

不要在onSaveInstanceState中注销,因为如果用户亦如历史堆栈中,这样将不能被called;

Reciver的生命周期

广播接收者的对象只有在回调onReceive()这个函数时有效,一旦从这个函数返回,这个对象就被结束,不再激活。

在onReceive()中,任何异步的操作都是不可行的。因为需要从onRecive()这个函数回来去处理异步的操作,但是这个广播接收者不再被激活,系统将会在异步操

完成前结束进程。特别是在这里面显示对话框或者绑定service不行,但是可以用其他替代的方式,前者可以notificationManger,后者用startService()发送请求。

BroadcastReceiver相关的函数:

Context.sendBroadcast()

发送的是普通广播,所有订阅者都有机会获得并进行处理。

Context.sendOrderedBroadcast()

发送的是有序广播,系统会根据接收者声明的优先级别按顺序逐个执行接收者,前面的接收者有权终止广播

BroadcastReceiver.abortBroadcast(),如果广播被前面的接收者终止,后面的接收者就再也无法获取到广播。对于有序广播,前面的接收者可以将处理结果存放进

广播Intent,然后传给下一个接收者。


上代码:

结果1:

结果2:

结果3:

结果4:

BroadcastDemoActivity.java

注1:

静态注册,就是在androidMainfest.xml中注册


注2:

触发Test1BroadCastReceiver,Test1BroadCastReceiver和动态注册的INTENAL_ACTION_1

注3:这里加了权限,BLUETOOTH_PERMISSION是蓝牙的权限,如果没有在androidMainifest.xml中加了权限,则会收不到;

注4:

动态注册BroadcastReceiver

通过registerReceiver(mBroadcastIntent, intentFilter);注册mBroadcastIntent

增加action;

在unregisterReceiver(mBroadcastIntent);中注销;

在中接收BroadcastReceiver mBroadcastIntent中处理;

注5:

注册多个广播

注册多个action,Intent.ACTION_BATTERY_CHANGED(系统的,测试电池变化),INTENAL_ACTION_3

注6:

接收Intent.ACTION_BATTERY_CHANGED.equals(action),INTENAL_ACTION_3.equals(action);

通过action判断是哪个广播发送的;

注7:

发送有序的broadcast;

增加了权限,权限值越大,优先级越高;

如果把权限值都去掉,则结果无法预料:

TestBroadCastReceiver.java

BroadcastReceiver实现接收者;

bundle,是接受广播的信息;

Test1BroadCastReceiver.java

main.xml


AndroidMainifest.xml
增加蓝牙权限静态注册了TestBroadCastReceiver,Test1BroadCastReceiver;


开发BroadcastReceiver的一些注意事项:

BroadcastReceiver的生命周期比较短,一些比较费时的操作不应该放在onReceiver里完成。如果在onReceiver()的方法不能在10秒内执行完成,将会产生程序无响应也就是我们熟悉的ANR(Application not Response)。但是如果非得要在这里面执行一些费时的操作我们可以在这个onReceiver去启动一个Service来完成这样的一个费时操作

附加功能,开机通过broadcast启动service;

在androidMainfest.xml中增加权限

首先开机启动后系统会发出一个Standard Broadcast Action,名字叫android.intent.action.BOOT_COMPLETED,这个Action只会发出一次

在receiver中增加

只要在接受者启动service就可以了。。。。。。。。。。



有问题请留言或者发邮箱:ligexiao@gmial.com


源代码下载源代码下载


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics