BroadcastReceiver

说说android四大丸子中的最简单的一个,android的dev Guide都不屑写篇文字来指导
那我们先看看api吧
一个基本类用来接收由sendBroadcast()发送的intents。可以通过AndroidManifest.xml的<receiver>标签 静态注册,或者使用 registerReceiver(BroadcastReceiver, IntentFilter)这样来 动态注册。api说如果在Activity.onResume()中registerReceiver了,那么在Activity.onPause()就应该调用unRegisterReceiver。 必须是成对的匹配,这个很重要,否则就会出现泄漏


主要有两类broadcasts被接收到:
Context.sendBroadcast,这个是完全的异步的,所有的receiver都处于一个无序的状态来接收,而且经常是同时的。
Context.sendOrderedBroadcast, 这个一次只能有一个receiver来接收的。每一个receiver按照顺序来执行,它可以传播result给下一个receiver,或者可以中断这个广播,这样其他的receiver就收不到任何信息。这个顺序是通过 android:priority属性在匹配intent-filter时候;receivers在同一个优先级是任意的顺序(比如说线控的就是这样的)。

即使是正常的broadcasts,系统也会采取某些策略来让这些receivers来一个个的处理。因为实际上,receivers们可能需要创建进程,一个个的执行可以防止系统因为过载。但是,在这种无序的策略下,receiver是不能对广播进行中断的。

Receiver Lifecycle &&Process Lifecyclebroadcast receiver只有一个回调方法:
void onReceive(Context curContext, Intent broadcastMsg)
 当经过receiver 请求,broadcast message到达的时候, Android 调用持有message的intent的 onReceive() 方法,只有broadcast receivers执行此方法的时候才是激活的,当 onReceive()返回的时候,它就是非激活状态 
一个含有激活的broadcast receiver的进程是不会被中止的。但是只含有非激活组件的进程在它占用的内存被其他程序请求的时候,任何时间都可以被中止。 

当响应broadcast message的程序因为消耗很多时间而在另外一个线程 而非UI所在的线程处理的时候会出现一个问题,,当 onReceive() 开启一个线程并返回后,整个程序(包括新建的线程)状态是非激活的(除非此进程中有其他激活的组件), 因此这个进程就有被中止的危险。 解决这个问题的办法是onReceive() 方法启动一个service,让sercie去做耗时的工作,这样系统就知道此进程中还有活动的工作。 
另外,在onReceive中不要弹出dialog和bind service,前者可以通过NotificationManager弹出通知,后者可以通过startservice来代替
//  要想在Service中启动Activity,必须设置如下标志  
activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
context.startActivity(activityIntent);  

非activity的话都没有task的概念了,所以都要有Intent.FLAG_ACTIVITY_NEW_TASK这个标示


Permissions

在发送时使用权限,我们提供了非空权限的方法 sendBroadcast(Intent, String) or sendOrderedBroadcast(Intent, String, BroadcastReceiver, android.os.Handler, int, String, Bundle)。只有receiver在被授权的时候才可以接收这些广播。

在接收的时候使用权限,我们提供了非空的权限的方法 registerReceiver(BroadcastReceiver, IntentFilter, String, android.os.Handler)或者在<receiver>标签在AndroidManifest.xml添加权限。只有那些被授权的才可以发intent到这些receiver,比如说在AndroidManifest.xml中添加相应的<uses-permission>标签。


下面的是大家的简介,更加通俗易懂,参考自http://flyvenus.net/wordpress/?p=176

在实际应用中,我们常需要等,等待系统抑或其他应用发出一道指令,为自己的应用擦亮明灯指明方向。而这种等待,在很多的平台上,都会需要付出不小的代价。

比如,在Symbian中,你要等待一个来电消息,显示归属地之类的,必须让自己的应用忍辱负重偷偷摸摸的开机启动,消隐图标隐藏任务项,潜伏在后台,监控着相关事件,等待转瞬即逝的出手机会。这是一件很发指的事情,不但白白耗费了系统资源,还留了个流氓软件的骂名,这真是卖力不讨好的正面典型。

在Android中,充分考虑了广泛的这类需求,于是就有了Broadcast Receiver这样的一个组件。每个Broadcast Receiver都可以接收一种或若干种Intent作为触发事件(有不知道Intent的么,后面会知道了…),当发生这样事件的时候,系统会负责唤醒或传递消息到该Broadcast Receiver,任其处置。在此之前和这以后,Broadcast Receiver是否在运行都变得不重要了,及其绿色环保。

这个实现机制,显然是基于一种注册方式的,Broadcast Receiver将其特征描述并注册在系统中,根据注册时机,可以分为两类,被我冠名为冷热插拔。所谓冷插拔,就是Broadcast Receiver的相关信息写在配置文件中(求配置文件详情?稍安,后续奉上…),系统会负责在相关事件发生的时候及时通知到该Broadcast Receiver,这种模式适合于这样的场景。某事件方式 -> 通知Broadcast -> 启动相关处理应用。比如,监听来电、邮件、短信之类的,都隶属于这种模式。而热插拔,顾名思义,插拔这样的事情,都是由应用自己来处理的,通常是在OnResume事件中通过registerReceiver进行注册,在OnPause等事件中反注册,通过这种方式使其能够在运行期间保持对相关事件的关注。比如,一款优秀的词典软件(比如,有道词典…),可能会有在运行期间关注网络状况变化的需求,使其可以在有廉价网络的时候优先使用网络查询词汇,在其他情况下,首先通过本地词库来查词,从而兼顾腰包和体验,一举两得一石二鸟一箭双雕(注,真实在有道词典中有这样的能力,但不是通过Broadcast Receiver实现的,仅以为例…)。而这样的监听,只需要在其工作状态下保持就好,不运行的时候,管你是天大的网路变化,与我何干。其模式可以归结为:启动应用 -> 监听事件 -> 发生时进行处理

除了接受消息的一方有多种模式,发送者也有很重要的选择权。通常,发送这有两类,一个就是系统本身,我们称之为系统Broadcast消息,在reference/android/content/Intent.htmlStandard Broadcast Actions,可以求到相关消息的详情。除了系统,自定义的应用可以放出Broadcast消息,通过的接口可以是Context.sendBroadcast,抑或是Context.sendOrderedBroadcast。前者发出的称为Normal broadcast,所有关注该消息的Receiver,都有机会获得并进行处理;后者放出的称作Ordered broadcasts,顾名思义,接受者需要按资排辈,排在后面的只能吃前面吃剩下的,前面的心情不好私吞了,后面的只能喝西北风了。

当Broadcast Receiver接收到相关的消息,它们通常做一些简单的处理,然后转化称为一条Notification,一次振铃,一次震动,抑或是启动一个Activity进行进一步的交互和处理。所以,虽然Broadcast整个逻辑不复杂,却是足够有用和好用,它统一了Android的事件广播模型,让很多平台都相形见绌了。更多Broadcast Receiver相关内容,参见:/reference/android/content/BroadcastReceiver.html


http://android.docs.uu3g.com/reference/android/content/BroadcastReceiver.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值