现象
最近有报问题说设置中某些按钮是灰色的,不可以清除。本着好奇的心态看了下设置中按钮为会的逻辑。原来原生系统中并不是对所有的应用都可以清除缓存和存储空间的。
分析
通过查找关键字定位到AppStorageSettings.java
这个文件中, 关键代码在initDataButtons
函数中。
if ((!appHasSpaceManagementUI && appRestrictsClearingData)
|| !isManageSpaceActivityAvailable) {
mButtonsPref
.setButton1Text(R.string.clear_user_data_text)
.setButton1Enabled(false);
mCanClearData = false;
}
通过以上代码可以看出有三个变量决定了清除按钮为可用appHasSpaceManagementUI
、appRestrictsClearingData
和isManageSpaceActivityAvailable
。
final boolean appHasSpaceManagementUI = mAppEntry.info.manageSpaceActivityName != null;
final boolean appHasActiveAdmins = mDpm.packageHasActiveAdmins(mPackageName);
// Check that SYSTEM_APP flag is set, and ALLOW_CLEAR_USER_DATA is not set.
final boolean isNonClearableSystemApp =
(mAppEntry.info.flags & (FLAG_SYSTEM | FLAG_ALLOW_CLEAR_USER_DATA)) == FLAG_SYSTEM;
final boolean appRestrictsClearingData = isNonClearableSystemApp || appHasActiveAdmins;
appHasSpaceManagementUI
官方定义主要是用来管理空间的。
/**
* Class implementing the Application's manage space
* functionality. From the "manageSpaceActivity"
* attribute. This is an optional attribute and will be null if
* applications don't specify it in their manifest
*/
public String manageSpaceActivityName;
在应用安装的时候会赋值parseBaseApplication
:
String manageSpaceActivity = sa.getNonConfigurationString(
com.android.internal.R.styleable.AndroidManifestApplication_manageSpaceActivity,
Configuration.NATIVE_CONFIG_VERSION);
if (manageSpaceActivity != null) {
ai.manageSpaceActivityName = buildClassName(pkgName, manageSpaceActivity,
outError);
}
应用是否可以禁止卸载和安装
* Used by package administration code to determine if a package can be stopped
* or uninstalled.
* @hide
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
public boolean packageHasActiveAdmins(String packageName) {
return packageHasActiveAdmins(packageName, myUserId());
}
最后一个isNonClearableSystemApp
就比较简单了,主要是看appinfo中是否被置为FLAG_SYSTEM
级系统app。
总结
通过以上变量可以控制app的数据是否被清除,在自定义应用行为的时候,如果不希望某些应用数据被删除,也可以参考以上方式来进行实现。