android为广播加上FLAG_EXCLUDE_STOPPED_PACKAGES

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_27196493/article/details/82531163

自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标志了。

猜你喜欢

转载自blog.csdn.net/baidu_27196493/article/details/82531163