現象
最近有報問題說設置中某些按鈕是灰色的,不可以清除。本著好奇的心態看了下設置中按鈕為會的邏輯。原來原生系統中并不是對所有的應用都可以清除緩存和存儲空間的。
分析
通過查找關鍵字定位到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的數據是否被清除,在自定義應用行為的時候,如果不希望某些應用數據被刪除,也可以參考以上方式來進行實現。