android 读取U盘apk文件信息,拔掉U盘导致进程被杀
来源:互联网 发布:汪峰 知乎 编辑:程序博客网 时间:2024/05/22 04:35
最近一直在搞appStore,之前一直都是从网络获取apk下载进行安装,现在车机要求需要支持从U盘安装apk,本以为简单很容易的事,却一不小心掉了一个坑里,爬了好久,主要是没很明显的报错,没遇到过的话真的很难发现错误。
一、首先来看下错误,以及造成的错误原因
由上图可知,当U盘拔掉之后,网易云音乐apk依旧被占用,从而系统发出了sighup,kill信号,导致当前进程被杀掉,也就是说我们读取apk信息时,资源未能及时释放。
二、解决思路,解决方案
既然是因为U盘拔掉后,资源未释放引起的,那解决的方案无非就是找到占用的地方,释放掉资源。然而你会发现你将所有可能引起的资源占用都处理置空,拔掉U盘时,将数据清空,还是会奔溃。具体原因以及解决思路可以看看这两篇博客
关于Usb直接拔出导致的进程崩溃问题
Android 开发:加载未安装apk图标-拔出U盘导致进程被杀的解决方案
上述两篇博客已经讲的很详细了,引起原因以及解决方案,都提供了不同的思路,但是他们只是针对,获取apk的图标,可能他们的需求只是需要个图标而已,针对图标进行了操作,但是在我的应用中,不仅仅需要图标,还需要应用的版本,名称,包名等等信息,从而我进行了各种尝试,确实如果我只是获取图标,通过他们的方式确实不会再出现进程被杀的情况,但是当我将所有需要的其他信息,依旧会报错。
三、我的做法,以及解决思路
首先先上代码:
public static UninstallApkInfo cloneUninstallAPKInfo(Context ctx, String archiveFilePath) { UninstallApkInfo uninstallApkInfo = new UninstallApkInfo(); Log.i("Apkinfo", "parse " + archiveFilePath); PackageInfo pakinfo = null; PackageManager pm = ctx.getPackageManager(); pakinfo = pm.getPackageArchiveInfo(archiveFilePath, PackageManager.GET_ACTIVITIES); if (pakinfo != null) { ApplicationInfo appinfo = pakinfo.applicationInfo; appinfo.sourceDir = archiveFilePath; appinfo.publicSourceDir = archiveFilePath; uninstallApkInfo.setAppVersion(pakinfo.versionName); // uninstallApkInfo.setAppName(pm.getApplicationLabel(appinfo).toString());// 得到应用名 ); // uninstallApkInfo.setAppIcon(appinfo.loadIcon(pm));//得到应用图标 uninstallApkInfo.setAppPkgName(appinfo.packageName); uninstallApkInfo.setFileName(archiveFilePath); uninstallApkInfo.setInstallState(ApkOperateManager.INSTALL_NONE); AssetManager assetManager = new AssetManager(); assetManager.addAssetPath(archiveFilePath); Resources resources = new Resources(assetManager, ctx.getResources().getDisplayMetrics(), ctx.getResources().getConfiguration()); uninstallApkInfo.setAppIcon(resources.getDrawable(appinfo.icon)); uninstallApkInfo.setAppName(resources.getString(appinfo.labelRes)); assetManager.close(); File file = new File(archiveFilePath); uninstallApkInfo.setAppSize(file.length() / (1024 * 1024)); Log.i("UN", uninstallApkInfo.appName + uninstallApkInfo.appPkgName); } else { Log.w("Apkinfo", "get no pkginfo from " + archiveFilePath); } if (pakinfo == null) return null; else return uninstallApkInfo; }
以上代码是不会出现U盘被占用的情况,首先对比一下我获取appName跟appIcon,注释的是我之前会出错的写法,然后再看看我现在获取的方式,首先先看出错的写法,我们用到了PackageManager(pm)跟PackageInfo(pakinfo),而现在的获取方式只是通过PackageInfo,我们进源码可以看到PackageInfo只是一个javaBean实现了Parcelable接口,也就是说PackageInfo只是用来放置apk里面的信息数据的,并没有进行实际的文件操作,我的理解是,读取apk文件信息的操作应该可能是放在PackageManager里面进行的,当我们用PackageManager来获取图标或者应用名时,PackageManager因为被我们引用了从而无法回收释放资源,而我们只用到PackageInfo,PackageManager也就能成功释放掉了,也就不会再占用U盘文件了。(仅代表个人见解,如有不对的地方或者更深的理解请指教)
好了U盘占用问题得到了解决,现在又遇到了一个问题就是只通过PackageInfo并不能获取到图标跟应用名信息,可是我们就是需要啊,那该怎么办?从上面提到的第二遍博客得到了解决的方案,有兴趣的可以看那篇博客得到更详细的说明,PackageInfo里面的ApplicationInfo里面含有图标资源和应用名的资源id,然后再通过AssetManager 来获取apk的resources,从而通过资源id得到apk的图标和应用名,并且AssetManager提供了close方法,所以获取到之后及时关闭资源也就不会出现U盘占用的问题了.
AssetManager assetManager = new AssetManager(); assetManager.addAssetPath(archiveFilePath); Resources resources = new Resources(assetManager, ctx.getResources().getDisplayMetrics(), ctx.getResources().getConfiguration()); uninstallApkInfo.setAppIcon(resources.getDrawable(appinfo.icon)); uninstallApkInfo.setAppName(resources.getString(appinfo.labelRes)); assetManager.close();
说明:AssetManager的所需要的几个方法都是隐藏的(@hide),我这边AssetManager能直接调用,是因为我们系统是自己定制的,已经让系统层那边将这些接口暴露了,如果你们系统是可以自己定制的,那么你可以采用跟我一样的方式让系统层暴露接口,否则你只能通过反射来调用这些接口,不会的话可以查看上面推荐的第二遍博客里面的第三个方案。
阅读全文
0 0
- android 读取U盘apk文件信息,拔掉U盘导致进程被杀
- android 读取U盘apk文件信息,拔掉U盘导致进程被杀
- Android 开发:加载未安装apk图标-拔出U盘导致进程被杀的解决方案
- android 读取U盘
- linux下无法识别u盘 因为U盘在使用就拔掉U盘
- U盘引导安装CentOS,拔掉U盘后无法启动的问题
- U盘安装Centos6.3 拔掉U盘后无法进入系统
- 不能在U盘目录下拔掉U盘的一种解决方法
- U盘安装单系统ubuntu10.04之全过程&拔掉U盘后系统无法启动
- java获得U盘根目录、读取图片视频头文件信息、获取视频时长
- 读取U盘 PID,VID,序列号等信息.
- 读取U盘 PID,VID,SN等信息
- PhotoFamily导致U盘一插入就马上打开U盘上所有文件目录
- Android 在扫描U盘解析图片缩略图时,拔出U盘导致崩溃
- android 4.2 apk中实现卸载U盘
- 拔掉U盘时提示无法停止使用通用卷问题如何解决
- U盘不能卸载,直接拔掉再插入提示:“目录损坏
- 读取U盘物理序列号
- html5学习2017.07.07
- 树中相关计算
- 翻车笔记:openjudge8469:特殊密码锁
- 揭秘 DeepMind 的关系推理网络
- git config git ssh git https
- android 读取U盘apk文件信息,拔掉U盘导致进程被杀
- 更改目录及子文件所有者及所属组
- com.Android.build.api.transform.TransformException:Java.util.zip.ZipException异常
- 微信竟然不能打开淘宝
- webpack中的HtmlWebpackPlugin
- HTML5基础入门
- Springmvc AOP拦截Controller获取session(自定义注解的方式)
- MATLAB中fft频谱图分析
- 《Hadoop生态》——第二章 数据库与数据管理——Hive