文章标题

在某些特定的场景下开发者希望动态的控制组件的生命周期:即该组件只运行一次, 之后就处于deactive状态不再被激活, 这时就需要用到PMS提供的接口setComponentEnabledSetting:
/**
* Set the enabled setting for a package component (activity, receiver, service, provider).
* This setting will override any enabled state which may have been set by the component in its
* manifest.
*
* @param componentName The component to enable
* @param newState The new enabled state for the component. The legal values for this state
* are:
* {@link #COMPONENT_ENABLED_STATE_ENABLED},
* {@link #COMPONENT_ENABLED_STATE_DISABLED}
* and
* {@link #COMPONENT_ENABLED_STATE_DEFAULT}
* The last one removes the setting, thereby restoring the component’s state to
* whatever was set in it’s manifest (or enabled, by default).
* @param flags Optional behavior flags: {@link #DONT_KILL_APP} or 0.
*/
public abstract void setComponentEnabledSetting(ComponentName componentName,
int newState, int flags);
通过Google源码注释可以看出:setComponentEnabledSetting接口可以禁用/启用系统四大组件, 并且它将会覆盖该组件在AndroidManifest.xml中”android:enabled=true/false”的定义(默认为true).
由继承关系可知该接口最终会调用到PackageManagerService中的setEnabledSetting:
–>PackageManager.setComponentEnabledSetting
–>ApplicationPackageManager.setComponentEnabledSetting
–>PackageManagerService.setComponentEnabledSetting-
–>PackageManagerService.setEnabledSetting
1.
private void setEnabledSetting(final String packageName, String className, int newState,
final int flags, int userId, String callingPackage) {
/参数检查:newState只能为以下几种状态,其中COMPONENT_ENABLED_STATE_DISABLED_USER和COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED只 适用于setApplicationEnabledSetting接口/
if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
|| newState == COMPONENT_ENABLED_STATE_ENABLED
|| newState == COMPONENT_ENABLED_STATE_DISABLED
|| newState == COMPONENT_ENABLED_STATE_DISABLED_USER
|| newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
throw new IllegalArgumentException(“Invalid new component state: ”
+ newState);
}
PackageSetting pkgSetting;
final int uid = Binder.getCallingUid();
final int permission;
/非系统应用需要声明android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE权限/
if (uid == Process.SYSTEM_UID) {
permission = PackageManager.PERMISSION_GRANTED;
} else {
permission = mContext.checkCallingOrSelfPermission(
android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
}
enforceCrossUserPermission(uid, userId,
false /* requireFullPermission /, true / checkShell */, “set enabled”);


switch (newState) {
case COMPONENT_ENABLED_STATE_ENABLED:
if (!pkgSetting.enableComponentLPw(className, userId)) {
return;
}
break;
/以禁用为例:更新PackageUserState中的enabledComponents和disabledComponents/
case COMPONENT_ENABLED_STATE_DISABLED:
if (!pkgSetting.disableComponentLPw(className, userId)) {
return;
}
break;
case COMPONENT_ENABLED_STATE_DEFAULT:
if (!pkgSetting.restoreComponentLPw(className, userId)) {
return;
}
break;
default:
Slog.e(TAG, “Invalid new component state: ” + newState);
return;
}

/最重要的部分就是将更新后的组件状态保存到文件中/
scheduleWritePackageRestrictionsLocked(userId);
/立即或者延时10s发送广播Intent.ACTION_PACKAGE_CHANGED/
try {
if (sendNow) {
packageUid = UserHandle.getUid(userId, pkgSetting.appId);
sendPackageChangedBroadcast(packageName,
(flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
}
} finally {
Binder.restoreCallingIdentity(callingId);
}
2.
–>PackageManagerServicescheduleWritePackageRestrictionsLocked
–>Settings.writePackageRestrictionsLPr
void writePackageRestrictionsLPr(int userId) {
if (DEBUG_MU) {
Log.i(TAG, “Writing package restrictions for user=” + userId);
}
// Keep the old stopped packages around until we know the new ones have
// been successfully written.
//文件路径:/data/system/users/0/package-restrictions.xml;
//备份文件:/data/system/users/0/package-restrictions-backup.xml
File userPackagesStateFile = getUserPackagesStateFile(userId);
File backupFile = getUserPackagesStateBackupFile(userId);
……..
//将第1步PackageUserState中保存的enabledComponents保存在文件中的enabled-components字段

            if (!ArrayUtils.isEmpty(ustate.enabledComponents)) {
                serializer.startTag(null, TAG_ENABLED_COMPONENTS);
                for (final String name : ustate.enabledComponents) {
                    serializer.startTag(null, TAG_ITEM);
                    serializer.attribute(null, ATTR_NAME, name);
                    serializer.endTag(null, TAG_ITEM);
                }
                serializer.endTag(null, TAG_ENABLED_COMPONENTS);
            }
            //将第1步PackageUserState中保存的disabledComponents保存在文件中的diabled-components字段
            if (!ArrayUtils.isEmpty(ustate.disabledComponents)) {
                serializer.startTag(null, TAG_DISABLED_COMPONENTS);
                for (final String name : ustate.disabledComponents) {
                    serializer.startTag(null, TAG_ITEM);
                    serializer.attribute(null, ATTR_NAME, name);
                    serializer.endTag(null, TAG_ITEM);
                }
                serializer.endTag(null, TAG_DISABLED_COMPONENTS);
            }
        ........
        //更新preferred-activities+persistent-preferred-activities+crossProfile-intent-filters+default-apps字段
        writePreferredActivitiesLPr(serializer, userId, true);
        writePersistentPreferredActivitiesLPr(serializer, userId);
        writeCrossProfileIntentFiltersLPr(serializer, userId);
        writeDefaultAppsLPr(serializer, userId);

至此设置阶段的工作基本完成.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值