活跃与非活跃
每个广播接收者都实现了回调方法 void onReceive(Context curContext, Intent broadcastMsg)
广播接收者有2种状态,活跃与非活跃,在执行onReceive的时候就是活跃状态,其他时候为非活跃状态
有一个活跃的广播接收者的进程是受保护的,不会被杀死。
onReceive处理耗时任务
BroadcastReceiver在10s内无法处理完成相关任务就会产生ANR
如果在onReceive要处理非常复杂的任务就可能产生ANR,因此我们想在onReceive起个子线程,交由子线程处理,onReceive先返回,这样不会产生ANR,但是BroadcastReceiver是不活跃的,进程可能被杀死,正在工作的子线程当然也会被杀死。
合适的方法是onReceive()启动一个服务,在服务中启线程做这个工作。
那为什么不直接在onReceive里启线程呢?为什么要起个service,在service里启线程呢?
其实都是可以的,只是通过service起线程要好一些,使用service会使得进程优先级高一些,至少保证在服务进程这个级别,不容易被杀死,
可参考本人文章“android进程优先级,内存不足时杀进程顺序”
API11之后还有一种方法
API11以後可以調用goAsync()方法,這個方法會返回一個PendingResult對象,android系統會認為OnReceive()方法還沒有執行完成直到調用PendingResult.finish(),所以可以調用goAsync方法后,新开一个线程去执行耗時操作,執行完后調用PendingResult.finish()方法。這裡耗時的操作也不能超過10秒
有序广播和无序广播
BroadcastReceiver所对应的广播分两类:普通广播和有序广播。
普通广播:通过Context.sendBroadcast()方法来发送,它是完全异步的。
所有的receivers的执行顺序不确定,因此所有的receivers接收broadcast的顺序不确定。
这种方式效率更高,但是BroadcastReceiver无法使用setResult系列、getResult系列及abort(中止)系列API
有序广播:是通过Context.sendOrderedBroadcast来发送,所有的receiver依次执行。
BroadcastReceiver可以使用setResult系列函数来结果传给下一个BroadcastReceiver,通过getResult系列函数来取得上个BroadcastReceiver返回的结果,并可以abort系列函数来让系统丢弃该广播,使用该广播不再传送到别的BroadcastReceiver。
可以通过在intent-filter中设置android:priority属性来设置receiver的优先级,优先级相同的receiver其执行顺序不确定。
如果BroadcastReceiver是代码中注册的话,且其intent-filter拥有相同android:priority属性的话,先注册的将先收到广播。
有序广播,即从优先级别最高的广播接收器开始接收,接收完了如果没有丢弃,就下传给下一个次高优先级别的广播接收器进行处理,依次类推,直到最后。如果多个应用程序设置的优先级别相同,则谁先注册的广播,谁就可以优先接收到广播。
关于广播的定义,分为两种,动态注册和静态注册。
动态注册的广播接收器永远要快于静态注册的广播接收器,不管静态注册的广播接收器的优先级是否高于动态注册的广播接收器的优先级。
动态注册的广播不是常驻型的,他是跟随着activity的生命周期的。一般在开发中都会在onDestroy()方法中移除广播。静态注册的广播是常驻型的广播,也就是说当应用程序关闭的时候,如果有信息广播来,程序也会被系统调用。在同一优先级下,谁启动的快,谁将先收到广播。
http://drops.wooyun.org/tips/4393
有些广播只能通过动态方式注册,比如时间变化事件、屏幕亮灭事件、电量变更事件,因为这些事件触发频率通常很高,如果允许后台监听,会导致进程频繁创建和销毁,从而影响系统整体性能。
![](http://static.wooyun.org/20150211/2015021110415529643.jpg)