当前位置:   article > 正文

android icon动态加载,Aandroid 应用icon动态加载到launcher方法及framework分析

iconlucencyactivity

Android launcher动态加载应用icon的方法

在android 应用开发中,我们会遇到应用icon需要动态加载到launcher中的问题。

实现的方法是:

private PackageManager pm;

pm = context.getPackageManager();

pm.setComponentEnabledSetting(new ComponentName(context,"com.uid.pid.New1MainActivity"),PackageManager.COMPONENT_ENABLED_STATE_ENABLED,

PackageManager.DONT_KILL_APP);//加载到launcher中

pm.setComponentEnabledSetting(componentName,PackageManager.COMPONENT_ENABLED_STATE_DISABLED,

PackageManager.DONT_KILL_APP);//从launcher中remove

这个setComponentEnabledSetting 具体是怎么工作的,我们通过framework源码可以知道:

PackageManagerService.java

@Override

public void setComponentEnabledSetting(ComponentName componentName,

int newState, int flags, int userId) {

if (!sUserManager.exists(userId)) return;

/* SPRD: update label and icon for app @{ */

String packege = componentName.getPackageName();

Log.w(TAG, packege+" == "+newState+" == "+flags+" "+userId);

if(packege.startsWith("com.android.stk")){

isOpen = true;

}

/* @} */

Log.d(TAG, "kings:packageName=" + componentName.getPackageName()

+ ", className=" + componentName.getClassName());

setEnabledSetting(componentName.getPackageName(),

componentName.getClassName(), newState, flags, userId, null);

}

>

private void setEnabledSetting(final String packageName, String className, int newState,

final int flags, int userId, String callingPackage) {

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);

}

...

scheduleWritePackageRestrictionsLocked(userId);

...

}

void scheduleWritePackageRestrictionsLocked(int userId) {

if (!sUserManager.exists(userId)) return;

mDirtyUsers.add(userId);

if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {

mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);

}

}

case WRITE_PACKAGE_RESTRICTIONS: {

Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);

synchronized (mPackages) {

removeMessages(WRITE_PACKAGE_RESTRICTIONS);

for (int userId : mDirtyUsers) {

mSettings.writePackageRestrictionsLPr(userId);

}

mDirtyUsers.clear();

}

Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);

} break;

从上面可以知道最终调用Settings.java中的writePackageRestrictionsLPr()来实现。

SettingS.java

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.

File userPackagesStateFile = getUserPackagesStateFile(userId);

File backupFile = getUserPackagesStateBackupFile(userId);

new File(userPackagesStateFile.getParent()).mkdirs();

if (userPackagesStateFile.exists()) {

// Presence of backup settings file indicates that we failed

// to persist packages earlier. So preserve the older

// backup for future reference since the current packages

// might have been corrupted.

if (!backupFile.exists()) {

if (!userPackagesStateFile.renameTo(backupFile)) {

Slog.wtf(PackageManagerService.TAG,

"Unable to backup user packages state file, "

+ "current changes will be lost at reboot");

return;

}

} else {

userPackagesStateFile.delete();

Slog.w(PackageManagerService.TAG, "Preserving older stopped packages backup");

}

}

try {

final FileOutputStream fstr = new FileOutputStream(userPackagesStateFile);

final BufferedOutputStream str = new BufferedOutputStream(fstr);

final XmlSerializer serializer = new FastXmlSerializer();

serializer.setOutput(str, StandardCharsets.UTF_8.name());

serializer.startDocument(null, true);

serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);

serializer.startTag(null, TAG_PACKAGE_RESTRICTIONS);

for (final PackageSetting pkg : mPackages.values()) {

PackageUserState ustate = pkg.readUserState(userId);

if (ustate.stopped || ustate.notLaunched || !ustate.installed

|| ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT

|| ustate.hidden

|| (ustate.enabledComponents != null

&& ustate.enabledComponents.size() > 0)

|| (ustate.disabledComponents != null

&& ustate.disabledComponents.size() > 0)

|| ustate.blockUninstall

|| (ustate.domainVerificationStatus !=

PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED)) {

serializer.startTag(null, TAG_PACKAGE);

serializer.attribute(null, ATTR_NAME, pkg.name);

if (DEBUG_MU) Log.i(TAG, " pkg=" + pkg.name + ", state=" + ustate.enabled);

if (!ustate.installed) {

serializer.attribute(null, ATTR_INSTALLED, "false");

}

if (ustate.stopped) {

serializer.attribute(null, ATTR_STOPPED, "true");

}

if (ustate.notLaunched) {

serializer.attribute(null, ATTR_NOT_LAUNCHED, "true");

}

if (ustate.hidden) {

serializer.attribute(null, ATTR_HIDDEN, "true");

}

if (ustate.blockUninstall) {

serializer.attribute(null, ATTR_BLOCK_UNINSTALL, "true");

}

if (ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT) {

serializer.attribute(null, ATTR_ENABLED,

Integer.toString(ustate.enabled));

if (ustate.lastDisableAppCaller != null) {

serializer.attribute(null, ATTR_ENABLED_CALLER,

ustate.lastDisableAppCaller);

}

}

if (ustate.domainVerificationStatus !=

PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {

serializer.attribute(null, ATTR_DOMAIN_VERIFICATON_STATE,

Integer.toString(ustate.domainVerificationStatus));

}

if (ustate.appLinkGeneration != 0) {

serializer.attribute(null, ATTR_APP_LINK_GENERATION,

Integer.toString(ustate.appLinkGeneration));

}

if (ustate.enabledComponents != null

&& ustate.enabledComponents.size() > 0) {

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);

}

if (ustate.disabledComponents != null

&& ustate.disabledComponents.size() > 0) {

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);

}

serializer.endTag(null, TAG_PACKAGE);

}

}

writePreferredActivitiesLPr(serializer, userId, true);

writePersistentPreferredActivitiesLPr(serializer, userId);

writeCrossProfileIntentFiltersLPr(serializer, userId);

writeDefaultAppsLPr(serializer, userId);

serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS);

serializer.endDocument();

str.flush();

FileUtils.sync(fstr);

str.close();

// New settings successfully written, old ones are no longer

// needed.

backupFile.delete();

FileUtils.setPermissions(userPackagesStateFile.toString(),

FileUtils.S_IRUSR|FileUtils.S_IWUSR

|FileUtils.S_IRGRP|FileUtils.S_IWGRP,

-1, -1);

// Done, all is good!

return;

} catch(java.io.IOException e) {

Slog.wtf(PackageManagerService.TAG,

"Unable to write package manager user packages state, "

+ " current changes will be lost at reboot", e);

}

// Clean up partially written files

if (userPackagesStateFile.exists()) {

if (!userPackagesStateFile.delete()) {

Log.i(PackageManagerService.TAG, "Failed to clean up mangled file: "

+ mStoppedPackagesFilename);

}

}

}

通过上面接口发现,android最终将这些componame 保存到手机系统/data/system/users/0/package-restrictions.xml 中

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/865767
推荐阅读
相关标签
  

闽ICP备14008679号