很多人遇到过广播收不到的问题,比如Google Play推广安装广播没有收到等,诸如这些问题,又都是什么原因呢,这篇文章将进行回答.
从Android 3.1(HoneyComb) 也就是API 12开始,Android引入了一套新的启动控制,这就是程序的停止状态.那让我们看一下Google对于程序的停止状态的描述.
Starting from Android 3.1, the system’s package manager keeps track of applications that are in a stopped state and provides a means of controlling their launch from background processes and other applications. 从Android 3.1开始,系统的包管理器开始跟踪处理停止状态的程序.并且提供了方法来控制从后台进程或者其他程序对它们的启动. Note that an application’s stopped state is not the same as an Activity’s stopped state. The system manages those two stopped states separately. 注意 程序的停止状态和Activity的停止状态不同,系统会单独处理这两种状态. The platform defines two new intent flags that let a sender specify whether the Intent should be allowed to activate components in stopped application. Android平台提供了两个intent flags,用来让发送广播的一方决定广播是否需要同时发送给已经停止的程序. FLAG_INCLUDE_STOPPED_PACKAGES — Include intent filters of stopped applications in the list of potential targets to resolve against. 将已经支持的程序加入到能处理intent的目标处理者. FLAG_EXCLUDE_STOPPED_PACKAGES — Exclude intent filters of stopped applications from the list of potential targets. 在能处理intent的目标处理者中不包含已经停止的程序.
当如果intnet中没有或者设置了上面两个flag,在目标处理者中是包含已经处于停止的程序.但是注意,系统会为所有的广播intent增加FLAG_EXCLUDE_STOPPED_PACKAGES这个flag.
Note that the system adds FLAG_EXCLUDE_STOPPED_PACKAGES to all broadcast intents. It does this to prevent broadcasts from background services from inadvertently or unnecessarily launching components of stoppped applications. A background service or application can override this behavior by adding the FLAG_INCLUDE_STOPPED_PACKAGES flag to broadcast intents that should be allowed to activate stopped applications.
需要注意的是,系统会默认地对所有的广播intent增加一个FLAG_EXCLUDE_STOPPED_PACKAGES的flag,这样做的目的是为了阻止来自后台服务的广播不慎或者启动处于停止状态的程序的不必要的组件.
通常的intnet广播,处于停止状态的程序的receiver是无法接受到的.那么怎么才能让这些停止状态的程序接受到呢?可以这样做,在后台服务或者应用中发送广播时,增加一个FLAG_INCLUDE_STOPPED_PACKAGES 的flag,意思是包含处于停止状态的程序.这样就可以激活停止状态的程序.
正如上述引用指出,系统默认阻止广播intent发送给处于停止状态的程序包,实际上这是为了保证安全和省电需要.比如说网络变化的广播,如果某些程序注册监听,并且它在得到广播时,做一系列的网络操作,这样必然是很耗能源的.
当程序第一次安装并且没有启动,或者用户手动从程序管理将其停止后,程序都会处于停止状态.
adb shell am force-stop package-name