Android U盘(USB)直接拔出导致进程被杀死

现象:

拔出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;
}```
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章