春节期间,在家看过分析Android中应用启动器的代码分析。回来后好久没有巩固,也没有再看。直到最近又看书,才想起来看了点东西全忘了。这次就做个笔记,以后回来也方便追溯。
一、APK文件结构组成
APK文件我们可以理解成一些文件的集合在一起的一种特殊的压缩包文件,拿到apk文件后,可以将其后缀名修改为.zip,然后将其解压查看里面的目录文件组成。
- AndroidManifest.xml文件是Android项目的配置文件,组件声明,版本号,版本名称,权限列表等信息都会在该文件中进行说明。
- META-INF 该目录下存放的是签名信心,保证应用的安全性。
- classes.dex 该文件是应用中的java代码编译后可运行在Dalvik虚拟机上的文件。相较于运行在jvm上的class文件而言,dex文件经过了进一步的优化,速度快,体积小等特点。也可以说是专门为移动设备而设计的。
- res目录。该目录存放的是应用中使用到的资源文件,比如图片,布局等文件。
- resources.arc 该文件用于存放应用内使用到的字符串,尺寸,颜色等资源。
二、应用安装进程
当一个apk文件被拷贝到应用目录下面时,系统会自动识别该动作并且使用包管理器进行安装,包管理器能够监测到应用目录下的改变。应用安装程序会借助系统包管理器中的installPackage()方法;绝大多数的系统应用都放在/system/app目录下,另外在/system/priv-app目录下存放的是系统的核心应用,此目录下的应用可以使用系统级别的权限;Android中4.4版本开始添加的/system/priv-app目录。上面提到的installPackage()方法是一系列的方法,这些方法在PackageManagerService中进行了代码实现;
安装程序的过程大概分为以下几个步骤:
1.PackageInstallerActivity中首先会检查要安装的应用是否是可信任的程序;
2.PackageInstallerActivity中执行解析方法,该方法会解析apk文件,从其AndroidManifest.xml文件中获取其中列出的所有权限请求列表;
3.PackageInstallerActivity将应用所申请的权限以列表的形式提示给用户,也就是我们安装时看到的权限列表界面;
4.接下来就进入了正式的安装过程。开始安装后,系统会将apk文件拷贝到/data/app/目录下,因为安装是一个耗时过程,所以PackageManagerService会暂时生成一个.tmp临时文件;
5.安装进程通过调用PackageManagerService中的scanPackageLI()方法来进行包浏览;
6.创建存储应用数据的目录;
7.为安装的应用生成优化后的dex文件代码;我们提到过dex文件是Dalvik虚拟机能够直接运行的文件。
8.安装应用的最后一步,是将安装的应用的包名,权限列表等信息更新到/data/system/packages.xml文件中,该文件中存储了设备上安装的所有应用的包名及权限声明等信息;
另外:
Android应用还允许自定义权限,设备上安装应用时,子定义权限是以先注册的为优先级的;如果后安装的应用中包含了有已安装注册的自定义权限相同名字的权限,就会提示,以先注册的为准。
9.所有需要进行的操作都完成后,PackageManagerService会发送一个广播ACTION_PACKAGE_ADDED,通知有需要更新的组件进行更新,比如Luncher;
二、应用更新过程
应用的更新过程和安装的过程大致上是相似的。步骤也是遵循安装应用的步骤。
1.首先第一步,系统会进行包名的签名验证,判断将要安装的应用和已安装存在的应用的签名是否是同一个签名;
2.接下来进行真正的更新操作。系统一次只能更新一个应用,第一步就会杀掉其他正在更新的进程;
3.将将要更新的应用包从内核结构和相关数据库中移除,这一步移除的其实就是应用注册到内核的所有组件;
4.接下来和安装应用时一样,PackageManagerService会触发scanPackageLI()方法来浏览是否有其他额外的权限;
5.解析AndroidManifest.xml文件,为权限重新赋予权限;
6.最后,将包名信息及权限列表等内容更新保存到/data/system/packages.xml文件中并且PackageManagerService会接着发送一个PACKAGE_REPLACED的广播;
命令笔记:
adb中pm有很多的命令:
pm list permissions 列出设备中的所有权限
pm list packages 列出设备中安装的所有应用的包名
pm install packagename 安装某个应用
pm uninstall packagename 卸载某个应用
pm命令还有很多很多,pm help 可以查看pm相关命令。