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