现象:
拔出U盘文件管理器会被系统杀死:
04-01 11:30:47.252 1855-1894/system_process I/ActivityManager: Killing 11673:com.kangdexin.kdxfilemanager/1000 (adj 0): stop com.xxx.filemanager
04-01 11:31:25.736 1343-1352/? W/vold: Kill all processes that have opened the file on the disk /mnt/usb/0EAB-3BE3, retries 9: Device or resource busy
04-01 11:31:25.966 1343-1352/? E/ProcessKiller: Process com.xxxx.filemanager (12111) has open file /mnt/usb/0EAB-3BE3/thinkmap_debug_v_1.0.4_20181214.apk
04-01 11:31:25.966 1343-1352/? W/ProcessKiller: Sending Interrupt to process 12111
通过多次测试,发现只有U盘中存在APK文件时才会出现这个问题,分析log中得出:拔出U盘的时候,因为filemanager(文件管理器)占用了U盘中的xxx.apk文件,导致process被系统kill了,所以app就挂了。
解决方法:
1.屏蔽信号 sighup,kill信号,自己接受信号并且自己来处理,默认情况下,接受了该信号,就会kill掉调用他的进程
2.找到还有哪里占用资源的地方,统统释放掉。
3.使用可以解除对apk资源占用的方法来加载应用图标
目前自己使用的时第三种,通过AssetManager 来加载icon,然后调用它的close方法释放
public static Drawable getUninstallApkIcon(Context context, String apkPath) {
Resources res = getResource(context, apkPath);
PackageManager pm = context.getPackageManager();
PackageInfo info = pm.getPackageArchiveInfo(apkPath, PackageManager.GET_ACTIVITIES);
ApplicationInfo appInfo = info.applicationInfo;
if (appInfo.icon != 0) {
Drawable icon = res.getDrawable(appInfo.icon);
//AssetManager must be closed to avoid ProcessKiller after unmounting usb disk.
res.getAssets().close();
return icon;
}
return null;
}
public static Resources getResource(Context context, String apkPath) {
AssetManager assetManager = createAssetManager(apkPath);
return new Resources(assetManager, context.getResources().getDisplayMetrics(), context.getResources().getConfiguration());
}
//利用反射调用AssetManager的addAssetPath()方法
private static AssetManager createAssetManager(String apkPath) {
try {
AssetManager assetManager = AssetManager.class.newInstance();
AssetManager.class.getDeclaredMethod("addAssetPath", String.class).invoke(
assetManager, apkPath);
return assetManager;
} catch (Throwable th) {
th.printStackTrace();
}
return null;
}```