android 应用卸载流程分析 |
您所在的位置:网站首页 › 安卓系统删除软件在哪里 › android 应用卸载流程分析 |
参考了其他大神的一些方法, 1.简介:Android的每个应用程序,都有自己的可控的目录。在Setting/Application info里面,可以看到每个应用程序,都有Clear data和Clear cache选项。具体这些目录在哪里呢?用adb连接上设备。如果是连接真实设备,需要有设备的root权限。 在/data/data目录下,每个应用程序都有自己的目录,目录名就是应用程序在AndroidManifest.xml文件中定义的包。每个应用程序的代码,对自己的目录是有绝对的控制权限的。在每个目录下,一般有如下几个子目录: databases : 存放数据库 cache : 存放缓存数据 files : 存放应用程序自己控制的文件 lib : 存放使用的包 应用安装的流程及路径 应用安装涉及到如下几个目录: system/app 系统自带的应用程序,无法删除 data/app用户程序安装的目录,有删除权限。安装时把apk文件复制到此目录。 data/data存放应用程序的数据 Data/dalvik-cache将apk中的dex文件安装到dalvik-cache目录下(dex文件是dalvik虚拟机的可执行文件,其大小约为原始apk文件大小的四分之一) 安装过程:复制APK安装包到data/app目录下,解压并扫描安装包,把dex文件(Dalvik字节码)保存到dalvik-cache目录,并在data/data目录下创建对应的应用数据目录。 卸载过程:删除安装过程中在上述三个目录下创建的文件及目录。主要步骤如下: 1.从PMS的内部结构上删除acitivity、service、provider等信息 2.删除code、library和resource等信息 3.调用installd删除/data/data/packageName以及/data/dalvik-cache下面的文件 4.更新Settings中的package信息 2.具体分析当我们在Settings中的应用页面找到一个安装了的应用程序,并点击卸载后,就会发送一个Intent给UninstallerActivity,在UninstallerActivity最后会启动UninstallAppProgress的initView方法,并调用如下卸载函数: [java] view plain copy getPackageManager().deletePackage(mAppInfo.packageName, observer, mAllUsers ? PackageManager.DELETE_ALL_USERS : 0); 上面的mAllUsers默认是false。getPackageManager()函数的实现在ContextImpl.java,它最后会调用到ApplicantPackageManger.java的deletePackage方法:
[java] view plain copy public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) { try { mPM.deletePackageAsUser(packageName, observer, UserHandle.myUserId(), flags); } catch (RemoteException e) { // Should never happen! } } 通过Binder调用,我们来看PMS中的deletePackageAsUser方法:
[java] view plain copy public void deletePackageAsUser(final String packageName, final IPackageDeleteObserver observer, final int userId, final int flags) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.DELETE_PACKAGES, null); final int uid = Binder.getCallingUid(); if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) { try { observer.packageDeleted(packageName, PackageManager.DELETE_FAILED_USER_RESTRICTED); } catch (RemoteException re) { } return; } mHandler.post(new Runnable() { public void run() { mHandler.removeCallbacks(this); final int returnCode = deletePackageX(packageName, userId, flags); if (observer != null) { try { observer.packageDeleted(packageName, returnCode); } catch (RemoteException e) { Log.i(TAG, "Observer no longer exists."); } //end catch } //end if } //end run }); } 在deletePackageAsUser方法中,首先做权限检查,然后就调用deletePackageX方法去执行卸载任务: [java] view plain copy private int deletePackageX(String packageName, int userId, int flags) { final PackageRemovedInfo info = new PackageRemovedInfo(); final boolean res; boolean removedForAllUsers = false; boolean systemUpdate = false; int[] allUsers; boolean[] perUserInstalled; synchronized (mPackages) { PackageSetting ps = mSettings.mPackages.get(packageName); allUsers = sUserManager.getUserIds(); perUserInstalled = new boolean[allUsers.length]; for (int i = 0; i |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |