BroadCast Receiver详解

Broadcast Receiver 用于异步接收广播 Intent,主要有两个大类用于接收广播:


  • 普通广播 Normal BroadCasts 通过Context.sendBroadcast() 方法来发送,它是完全异步发送的。

所有的 Receiver (接收器)都运行在同一时间内,但是执行顺序未定。因此所有的 Receiver (接收器)接收 Broadcast 的顺序不确定。

这种方式效率更高,但是 Broadcast Receiver 无法使用 setResult、getResult 以及 abort (终止)系列 API 。

  • 有序广播 Ordered Broadcast 通过 Context.sendOrderedBroadcast() 方法来发送,所有的Receiver依次执行。

Broadcast Receiver 可以使用 setResult 系列函数把结果传给下一个Broadcast Receiver,通过 getResult 系列函数取得上个 Broadcast Receiver 返回的结果,

并且可以使用 abort 系列函数让系统丢弃该广播 , 使该广播不再传送给别的 BroadcastReceiver。

Broadcast Receiver运行的顺序可以通过 intent-filter 里面的 android:prority 属性来控制优先级。当 prority 优先级相同时,Receiver执行顺序不确定。

有序广播,即从优先级别最高的广播接收器开始接收,接收完了如果没有丢弃,就下传给下一个次高优先级别的广播接收器进行处理,依次类推,直到最后。如果多个应用程序设置的优先级别相同,则谁先注册的广播,谁就可以优先接收到广播。


注:即使是普通广播,系统在某些情况下也可能会恢复到一次只传播给一个 Receiver,特别是 Receiver 可能需要创建一个进程时,为了避免系统超载,只能一次运行一个 Receiver 。

Broadcast Receiver 并没有提供可视化的界面来显示广播信息,可以使用 Notification 和 Notification Manager 来实现可视化的信息界面, 显示广播信息的内容、图标以及震动信息 。

Broadcast Receiver 生命周期

Broadcast的生命周期只有一个回调方法:onReceive(Content curContext, Intent broadcastMsg)。

当Broadcast消息到达接收者时,Android会调用它的 onReceiver() 方法,并且传递包含这个信息的 Intent 对象,Broadcast 接收者在执行这个方法时,被认为是活动的,当 onReceive() 方法返回时,它停止活动的状态。

一个活动的广播接收者进程是不能被杀死的,但是当它所消耗的内存被别的进程需要时,一个非活动的进程可以被系统随时杀死。

这就带来一个问题,广播消息是非常耗时的,因此,很多事情需要在一个独立的线程中执行,而不是在主线程里。如果 onReceive() 方法启动一个线程,那么整个进程包括刚启动的线程,是非活动状态的 (除非进程里面有其他活动的应用程序组件),所以有被系统销毁的危险,这个问题的解决方法是在 onReceive() 方法里面启动一个服务,然后处理一些事情,这样系统就会知道在这个进程里仍然有处于活动状态的任务需要被处理。

Android操作系统尝试尽可能长时间的保持应用进程,但是可能内存很低的时候要移除一部分进程。

怎样确定哪些程序可以运行,哪些程序要被销毁呢? Android 让每一个进程在一个重要级上运行,重要级低的进程最有可能被淘汰,共五个重要级


  • 第一级 前台进程显示的是用户此时需要处理和显示的 。(下列条件有任何一个成立,这个进程都被认为是在前台运行的)

与用户正发生交互的

控制一个与用户交互的必须的基本服务

有一个正在调用生命周期回调函数的 Service (如 onCreate()、onStar()、 onDestroy())

它有一个正在运行的 onReceive() 方法的广播接收对象

  • 第二级 一个可能的进程没有任何前台组件,但它仍然可以影响到用户的界面。(下面两种情况发生时,可以称该进程为可用进程)

它是一个非前台的 Activity ,但对用户仍然可用(onPause() 方法已经被调用),例如:前台的 Activity 是一个允许上一个 Activity可见的对话框,即当前 Activity 半透明,能看到前一个活动界面。

它是一个服务于可用 Activity 的服务

  • 第三级 一个服务进程是一个通过调用 startService() 方法启动的服务,并且不属于前两种情况。尽管服务进程没有直接被用户看到,但是它们确实是用户所关心的。例如:后台播放音乐或者网络下载数据,所以系统要保证他们的运行,直到不能保证所有的前台可见程序都正常运行时才会终止他们。
  • 第四级 一个后台进程就是一个非当前正在运行的 Activity (Activity的 onStop() 方法已经被调用),他们不会对用户体验造成直接的影响,当没有足够的内存来运行前台可见的程序时,他们将会被终止。通常,后台进程会有很多个在运行,所以他们维护一个 LUR 最近使用程序来保证经常运行的 Activity能最后一个被终止。如果一个 Activity正确的实现了生命周期的方法,并保存了它当前的状态,杀死这些进程将不会影响到用户体验。
  • 第五级 一个空线程没有运行任何可用应用程序,保留他们的唯一原因是为了设立一个缓存机制,来加快组件启动的时间,系统经常杀死这些内存来平衡整个系统的资源、进程缓存和基本核心缓存之间的资源。
安卓把进程里优先级最高的 Activity 或 Service ,作为这个进程的优先级。例如:一个进程拥有一个服务和一个可见的 Activity,那么这个 进程将会被定义为可见进程,而不是服务进程。

此外,如果别的进程依赖某一个进程的话,那么被依赖的进程会提高优先级。一个进程服务于另一个进程,那么提供服务的进程不会低于获得服务的进程,例如:如果进程 A 的一个内容提供商服务于进程 B 的一个客户端, 或者进程 A 的一个 Service 被进程 B 的一个组件绑定, 那么进程 A 至少拥有和进程 B 一样的优先级,或者更高。

操作来启动一个服务,而不是启动一个线程--尤其是这个操作可能会拖垮这个activity。例如后台播放音乐的同时,通过照相机向服务器发送一张照片。启动一个服务会保证这个操作至少运行在service 进程的优先级下,无论这个activity发生了什么,广播接收者应该作为一个空服务而不是简单的把耗时的操作单独放在一个线程里

发送广播

事件的广播比较简单,构建 Intent 对象,可调用 sendBroadcast(Intent) 方法将广播发送出,另外还有 sendOrderedBroadcast()、sendStickyBroadcast() 等方法













  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值