APK安装时原来的apk安装信息没有被清掉产生安装垃圾问题的解决办法
2016-12-16 17:39
417 查看
问题描述:
下载三个apk(http://pan.baidu.com/s/1geS25r1):
问题:
任务:
问题1产生的原因:
问题2产生的原因:
问题2解决方式一(验证通过):
问题2解决方式二(验证通过):
2、若用户已安装过系统apk,然后回复出厂设置,再卸载该apk后,系统自带的该apk也不可使用,因为重复安装会直接删除system下的apk安装信息,而不会将其修改为update-package,此时,只有重启电视,系统才会重新安装system下的apk,然后可以正常使用(尝试继续研究解决办法)
问题2解决方式三(验证通过):
下载三个apk(http://pan.baidu.com/s/1geS25r1):
在android5.0 及以上平台: 1、将331.apk 替换掉系统内置的/system/vendor/app/SkyAppStore/SkyAppStore.apk ,并 rm -rf /data/data/com.tianci.appstore。rm -rf /data/app/com.tianci.appstore-xxx。 然后重启电视 2、pm install -r /mnt/usb/sda1/523.apk,恢复出厂设置:保留应用。问题1: 3、再次pm install -r /mnt/usb/sda1/622.apk,。 问题2:
问题:
1、电视重启后,通过pm path com.tianci.appstore发现,系统用的是system下的,而不是data下的 2、再次安装新的后,pm path com.tianci.appstore 使用的是data/app/com.tianci.appstore-2。而com.tianci.appstore-1还在。
任务:
1、查android源码,找出问题1/2的原因 2、提供解决方案:如何避免com.tianci.appstore-1垃圾的产生。
问题1产生的原因:
系统恢复出厂设置时会删除packages.xml和packages.list文件,这两个文件中记录的是系统已安装的应用信息,包括用户应用和系统应用,系统再次开机时,回会先扫描system下的app安装,之后才会扫描data下面的app进行安装,其中扫描安装过程中会调用一下两个判断(位于PackageManagerService.java):
if (mPackages.containsKey(pkg.packageName) || mSharedLibraries.containsKey(pkg.packageName)) { throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,"Application package " +pkg.packageName+ " already installed. Skipping duplicate."); }
这个判断是检查该apk是否已被安装过,若已被安装过得apk包含这个apk信息,则直接抛出异常不再重复安装,所以对于系统自带的apk,及时data下有也不会重新安装
if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) || !pkg.applicationInfo.getResourcePath().equals(known.resourcePathString)) { throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,"Application package " + pkg.packageName + " found at " + pkg.applicationInfo.getCodePath() + " but expected at " + known.codePathString + "; ignoring."); }
这个判断是检查当前要安装的apk路径与已被安装的apk的配置信息是否一致,若不一致则抛出异常,不再安装次apk,由于系统自带的apk的安装路径是指向system目录的,所以即使data下有该apk也不会更新apk的安装信息。 综上:系统恢复出厂设置后,及时data下也有系统自带apk的安装信息,也还是会使用system下的apk,而不会使用data下的apk。
问题2产生的原因:
private File getNextCodePath(String packageName) { int suffix = 1; File result; do { result = new File(mAppInstallDir, packageName + "-" + suffix); suffix++; } while (result.exists()); return result; }
pm install -r /mnt/usb/sda1/523.apk会调用以上函数来产生自己的安装文件夹,由次函数可以看出:如果检测到data/app下如果有此app的安装文件夹,则自动将后缀加1(suffix++;),pm install -r /mnt/usb/sda1/523.apk后会在data/app下产生com.tianci.appstore-1的文件夹,恢复出厂设置后,由于系统带有appstore的apk,所以系统会安装自带的apk,而此时data/app下的appstore的安装文件并没有被删掉,此时pm path com.tianci.appstore查看系统使用的app路劲会得到:/system/vendor/app/SkyAppStore/SkyAppStore.apk,即是用的系统apk,当再次pm install -r /mnt/usb/sda1/622.apk时,系统根据packages.xml只检测到了系统自带的apk,没有检测到之前用户自己安装过SkyAppStore.apk,所以再次安装的时候只会卸载掉系统apk(更新packages.xml,而不是把/system/vendor/app/SkyAppStore/SkyAppStore.apk删掉),然后调用getNextCodePath函数在data/app下产生自己的文件夹,此时就产生了com.tianci.appstore-1垃圾。
问题2解决方式一(验证通过):
pm install -r /mnt/usb/sda1/622.apk时,若data/app下已存在该包名的文件夹则直接删掉,修改getNextCodePath函数:
private File getNextCodePath(String packageName) { int suffix = 1; File result = new File(mAppInstallDir, packageName + "-" + suffix); for(;result.exists();) { if(result.isDirectory()) { FileUtils.deleteContents(result); } result.delete(); suffix++; result = new File(mAppInstallDir, packageName + "-" + suffix); } result = new File(mAppInstallDir, packageName + "-" + 1); return result; }
问题2解决方式二(验证通过):
回复出厂设置时,允许apk重复安装,等同于优先使用data下的apk,,注释掉两个判断即可:
/*
if (mPackages.containsKey(pkg.packageName) || mSharedLibraries.containsKey(pkg.packageName)) { throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,"Application package " +pkg.packageName+ " already installed. Skipping duplicate."); }*/
/*
if (!pkg.applicationInfo.getCodePath().equals(known.codePathString) || !pkg.applicationInfo.getResourcePath().equals(known.resourcePathString)) { throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,"Application package " + pkg.packageName + " found at " + pkg.applicationInfo.getCodePath() + " but expected at " + known.codePathString + "; ignoring."); }*/
潜在的问题:1、系统恢复出厂设置的原则是将系统回复到出厂状态,若使用此修改,相当于系统没有恢复到最原始的状态
2、若用户已安装过系统apk,然后回复出厂设置,再卸载该apk后,系统自带的该apk也不可使用,因为重复安装会直接删除system下的apk安装信息,而不会将其修改为update-package,此时,只有重启电视,系统才会重新安装system下的apk,然后可以正常使用(尝试继续研究解决办法)
问题2解决方式三(验证通过):
系统第一次开机时直接删除安装失败的软件包,mRestoredSettings是判断是否为第一次开机的标志。
// Delete invalid userdata apps if (((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 && e.error == PackageManager.INSTALL_FAILED_INVALID_APK) || !mRestoredSettings) { logCriticalInfo(Log.WARN, "Deleting invalid package at " + file); if (file.isDirectory()) { FileUtils.deleteContents(file); } file.delete(); }
潜在问题:若用户在升级到该系统版本前执行操作:pm install -r /mnt/usb/sda1/622.apk,然后恢复出厂设置,此时data/app下存在com.tianci.appstore-1,pm path com.tianci.appstore可以看到系统用的是system下的apk,这是系统升级到该版本,然后pm install -r /mnt/usb/sda1/622.apk会在data/app下产生com.tianci.appstore-2文件夹,需要再恢复一次出厂设置。
相关文章推荐
- 安装Ubuntu版本linux过程中没有提示设置root用户密码问题的解决办法
- MYSQL重复安装产生的问题解决办法
- 学习python的问题-安装Anaconda2时菜单栏没有快捷方式的解决办法
- 友盟集成微信分享,显示您的设备没有安装微信问题及解决办法
- Android安装包apk文件在某些版本操作系统上安装解析包出错问题的解决办法
- Android apk无法安装及闪退问题解决办法
- 解决APP在线更新时用户没有sdcard而产生的APK下载路径问题
- Eclipse安装了SpringSource Tool Suite插件后,编辑SpringBoot项目的yml配置文件仍然没有提示信息的解决办法
- pe模式安装win7(32位)的时候出现“安装程序无法定位现有系统分区,也无法创建新的系统分区”提示,网上很多对此问题没有很好的解决办法
- Android Studio升级到2.3.1,小米MI无法安装apk,安装失败,闪退,即时运行 失败,Session 'app': Error Installing APKs,问题解决办法
- 安装AndroidStudio出现问题 JDK安装后 没有tools.jar 和dt.jar包的解决办法
- 遇到错误-----安装DBD:MySql模块遇到的问题及解决办法Can't exec "mysql_config": 没有那个文件或目录 at Makefile.PL line 479.
- 遇到错误-----安装DBD:MySql模块遇到的问题及解决办法Can't exec "mysql_config": 没有那个文件或目录 at Makefile.PL line 479.
- 解决app在没有上传app store前大规模安装测试问题的一些办法与思路
- 解决app在没有上传app store前大规模安装测试问题的一些办法与思路
- Qt官方办法解决:Qt没有被正确安装,请运行make install问题的解决
- 怎么解决yum安装的时候rpm包没有办法下载的问题
- 安装Ubuntu版本linux过程中没有提示设置root用户密码问题的解决办法
- apk卸载不干净,导致安装、升级不成功问题的解决办法
- 解决app在没有上传app store前大规模安装测试问题的一些办法与思路