一、sendBroadcast方法是异步还是同步?接下来继续上一个demo的更改

1.首先修改onclick方法,该方法实现发送广播通知

Android 广播接收器接收多个广播_工作线程

2.然后在TestReceiver2中增加如下代码

Android 广播接收器接收多个广播_主线程_02

3.最后运行程序,结果如下?


sendBroadCast方法前后的日志都在接收程序日志之前,并且处于同一个线程中(main),这证明主线程正在运行并会处理来自消息队列的广播接收程序,所以sendBroadcast方法是异步的。

二、接收程序逻辑处理最好不要超过10s,如以下demo,我在接收程序中让其休眠10001ms(即超过10s)

Android 广播接收器接收多个广播_工作线程_03

执行结果

Android 广播接收器接收多个广播_工作线程_04

可一看到应用程序ANR了,那如果我们需要在接收程序中处理一些耗时的业务逻辑,那应该怎么办呢?

三、长期运行的接收程序和服务

1.关于广播接收程序的事实

.类似于在主线程执行的其他android组件

.持有广播接收程序的代码将持有主线程,并会导致ANR

.广播接收程序的时间限制是10s,而activity的是5s

.承载广播接收程序的进程将与广播接收程序的执行一起启动和终止

.与服务进程不同,广播接收程序进程不会重启

.Android在调用广播服务时获取一个部分的唤醒锁,并在它重主线程中的服务返回时释放它

ps:唤醒锁是这一种机制,用于避免设备休眠


2.长期运行的广播接收程序协议

a.在广播接收程序的onReceive方法中获取一个静态唤醒锁

b.启动一个本地服务,以便进程不会结束

c.在该服务中启动一个工作线程处理业务逻辑

ps:不要在服务的onStart方法中执行,因为这会再次持有主线程

d.当工作线程执行完成后,告诉服务直接或通过处理程序停止自身

e.让服务关闭静态唤醒锁


3.IntentService

IntentService并不是在主线程上执行,其内部是使用一个循环程序将请求添加到一个子线程队列中。下面是关于IntentService的官方描述:

Android 广播接收器接收多个广播_静态注册_05

 

4.demo

添加一个新类LongRunningService,该类继承于IntentService,现在项目结构如下

Android 广播接收器接收多个广播_主线程_06

修改广播接收程序,如下

Android 广播接收器接收多个广播_主线程_07

最后运行程序,结果如下

Android 广播接收器接收多个广播_主线程_08

可一看到10s后被唤醒,而且主程序并没有被卡死,还可以继续执行其他操作

综上,IntentService结合广播接收程序不会阻塞主线程,它会在工作线程中执行业务逻辑


四、多个接收者程序的执行顺序

a.都为静态注册

Android 广播接收器接收多个广播_主线程_09

Android 广播接收器接收多个广播_Android 广播接收器接收多个广播_10

Android 广播接收器接收多个广播_Android 广播接收器接收多个广播_11

Android 广播接收器接收多个广播_主线程_12

从以上几个图可以看出静态注册情况下接收程序的执行顺序依赖于注册文件中的配置顺序

2.静态注册和动态注册

Android 广播接收器接收多个广播_工作线程_13

Android 广播接收器接收多个广播_静态注册_14

Android 广播接收器接收多个广播_工作线程_15

可以看出动态注册的优先级高于静态注册