自android3.1之后,android就为广播增加了两个标志FLAG_EXCLUDE_STOPPED_PACKAGES和FLAG_INCLUDE_STOPPED_PACKAGES。android系统默认为我们的广播加上了FLAG_EXCLUDE_STOPPED_PACKAGES标志,我们从源码上来看一下是否如此。
首先我们从Activity的sendBroadcast方法跟起,该方法源码为:
@Override
public void sendBroadcast(Intent intent) {
mBase.sendBroadcast(intent);
}
可知其调用的是mBase的sendBroadcast,mBase的类型其实为ContextImpl,我们来看一下ContextImpl.sendBroadcast方法:
@Override
public void sendBroadcast(Intent intent, String receiverPermission, Bundle options) {
warnIfCallingFromSystemProcess();
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
String[] receiverPermissions = receiverPermission == null ? null
: new String[] {receiverPermission};
try {
intent.prepareToLeaveProcess(this);
ActivityManagerNative.getDefault().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
Activity.RESULT_OK, null, null, receiverPermissions, AppOpsManager.OP_NONE,
options, false, false, getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
最终调用的是ActivityManagerService.broadcastIntentLocked方法,该方法里面有下句代码会执行:
// By default broadcasts do not go to stopped apps.
intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
可知系统会默认为我们发送的广播加上FLAG_EXCLUDE_STOPPED_PACKAGES,使得处于stopped的应用无法收到广播,这样也是为了节省资源和电量。我们再看一下FLAG_EXCLUDE_STOPPED_PACKAGES和FLAG_INCLUDE_STOPPED_PACKAGES的定义:
/**
* If set, this intent will not match anycomponents in packages that
* are currently stopped. If this is not set, then the default behavior
* is to include such applications in theresult.
*/
public static final int FLAG_EXCLUDE_STOPPED_PACKAGES = 0x00000010;
/**
* If set, this intent will always matchany components in packages that
* are currently stopped. This is the default behavior when
* {@link #FLAG_EXCLUDE_STOPPED_PACKAGES}is not set. If both of these
* flags are set, this one wins (itallows overriding of exclude for
* places where the framework mayautomatically set the exclude flag).
*/
public static final int FLAG_INCLUDE_STOPPED_PACKAGES = 0x00000020;
根据注释可知,如果intent没有设置FLAG_EXCLUDE_STOPPED_PACKAGES,那么默认的行为是按照FLAG_INCLUDE_STOPPED_PACKAGES,如果两个flag都设置了,那么那么其作用的是FLAG_INCLUDE_STOPPED_PACKAGES。因为实际上系统为intent设置了FLAG_EXCLUDE_STOPPED_PACKAGE,所以如果我们想让广播能被stopped状态的应用收到,只能显示地为intent加上FLAG_INCLUDE_STOPPED_PACKAGES标志了。