最近一直在搞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;elsereturn 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能直接调用,是因为我们系统是自己定制的,已经让系统层那边将这些接口暴露了,如果你们系统是可以自己定制的,那么你可以采用跟我一样的方式让系统层暴露接口,否则你只能通过反射来调用这些接口,不会的话可以查看上面推荐的第二遍博客里面的第三个方案。

android 读取U盘apk文件信息,拔掉U盘导致进程被杀相关推荐

  1. android电视识别多区u盘,【当贝市场】电视无法识别U盘APK文件终极方法

    原标题:[当贝市场]电视无法识别U盘APK文件终极方法 相信很多用户在刚开始安装的时候,都会使用U盘下载APK文件,插到电脑上进行安装!可是突然电视不读取U盘的APK文件了怎么办呢? 原因: 很多电视 ...

  2. 将Eclipse Android项目打包成APK文件

    将Eclipse Android项目打包成APK文件是本文要介绍的内容,主要是来了解并学习Eclipse Android打包的内容,具体关于Eclipse Android内容的详解来看本文  . Ec ...

  3. Android项目打包生成apk文件

    Android开发打包生成APK文件 打包apk文件分为两种 无需密钥的apk 有密钥的apk(常规) 他们的区别只是就是安全问题. 1.没有密钥的apk 点击之后会自动生成没有密钥的APK. 在编辑 ...

  4. Android读取assets目录下文件数据内容

    Android读取assets目录下文件数据内容 Android的体系架构设计中,assets目录下的数据内容(图片.文件等等)将不会被Android系统压缩.二次处理等,assets目录下的文件 ...

  5. java eclipse生成apk,将Eclipse Android项目打包成APK文件

    将Eclipse Android项目打包成APK文件是本文要介绍的内容,主要是来了解并学习Eclipse Android打包的内容,具体关于Eclipse Android内容的详解来看本文. Ecli ...

  6. 如何在Android模拟器中安装APK文件?

    我终于设法混淆了我的Android应用程序,现在我想通过安装APK文件并在模拟器上运行来测试它. 如何在Android模拟器上安装APK文件? #1楼 从浏览器下载apk文件,然后点击它(通知区域). ...

  7. Android读取asserts和raw文件夹下的文件

    Android读取asserts和raw文件夹下的文件 经常需要用到读取"/res/raw"和"/asserts"文件夹下的文件,索性写成工具类方便以后使用. ...

  8. android pak文件_Android 获取手机中已安装apk文件信息

    通过PackageManager可以获取手机端已安装的apk文件的信息,具体代码如下 PackageManager packageManager = this.getPackageManager(); ...

  9. android获取未安装APK签名信息及MD5指纹

    站在巨人的肩膀上写博客: http://blog.csdn.net/wulianghuan/article/details/18400581 http://www.jb51.net/article/7 ...

最新文章

  1. Winform中实现图片格式转换(附代码下载)
  2. 为何Transformer在计算机视觉中如此受欢迎
  3. python 爬虫生成csv文件和图_python爬虫系列(4.2-python操作csv文件)
  4. 项目Beta冲刺(团队)总结
  5. Windows:定时/进程结束执行命令
  6. 建武28a对讲机最大距离_小米对讲机再出新品:不但价格低,还能一键写频
  7. 角谱 matlab,关于角谱法实现数字全息 - 程序语言 - MATLAB/Mathematica - 小木虫论坛-学术科研互动平台...
  8. Docker学习笔记08-----Docker Harbor使用详解
  9. 深入FM和FFM原理与实践
  10. 用idea对git的merge进行撤销
  11. 文本处理技能与文本数据清洗、提取、分词与统计
  12. IntelliJ IDEA 在使用manven后的纠结(每次修改代码都要重启tomcat才能看效果吗?),请各位大侠来看看问题
  13. java 耗时_Java中计算程序运行耗时的方法对比
  14. 解析java源文件_使用JDT.AST解析java源码
  15. 咸鱼前端—CSS高级技巧
  16. java as2_使用AS2(http)协议实现 B2B 商用数据交换 (二) [译]
  17. hackthebox的网站使用教程
  18. 第二阶段爬虫day1作业
  19. C语言int search类型,C语言的一些高级议题
  20. R语言:企业风险分析(3)【蒙特卡罗模拟的可视化,敏感性分析】

热门文章

  1. 【excel】多表汇总查询实现
  2. Cocos2d-HTML5入门第三天
  3. oracle复制粘贴不好使,Oracle SQL Developer 编辑区不能删除,后退,空格,复制粘贴等功能都失效的解决办法...
  4. Apache Dubbo的爱奇艺之旅
  5. 23种设计模式的学习
  6. 微信小程序账号被冻结,如何找回
  7. LoadRunner的安装破解教程
  8. 创业路上之做好人划算吗?
  9. pmp考试24计 | 第四计-见人说人话,见鬼说鬼话
  10. 【有利可图网】PS教程:用PS把人像调成简笔粉笔画效果