Android面试题(32)-android编译过程和安装流程

本文详细介绍了Android应用的编译过程,包括aapt工具生成R.java、aidl转换、java编译、dex生成、apk打包、签名与Zipalign优化。同时,探讨了Android App的四种安装方式,解析了安装流程中的关键步骤,如拷贝apk、解压、解析AndroidManifest.xml、创建数据目录等。最后,对比了Dalvik和ART虚拟机的差异。
摘要由CSDN通过智能技术生成

android app的编译过程

从网上拷了一张图

这张图很好的讲述了android的编译打包过程,接下来就具体的分析分析,大致分为7步:

(1)aapt(Android Asset Packaging Tool,android构建工具,在android-sdk的build-tool目录下)它的主要工作就是把项目中使用到的资源文件打包成R.java文件;

(2)aidl工具会将aidl接口转换为java接口

(3)java编译器就会将上述准备好的文件和我们在项目敲得java源文件打包成.class文件

       R.java文件+aidl接口+java源文件===>.class字节码文件;

(4)如果是java程序,把.class文件交给java虚拟机就可以了,但是android使用的不是java虚拟机,是davlik虚拟机,所以编译成.class文件还不行,还需要通过dex工具把.class文件打包成.dex文件,这里如果你项目中使用了第三方的库,也会在这里一起打包成.dex文件;

(5)通过apkbuilder工具将编译过的文件和那些没有编译过的文件(图片,视频等)加上上述的.dex文件一起打包成.apk文件;

(6)这时候的.apk文件还无法去使用,还需要通过Jarsigner这个工具对.apk进行签名,至于签名的原因:为了保证每个应用程序开发商合法ID,防止部分开放商可能通过使用相同的Package Name来混淆替换已经安装的程序,我们需要对我们发布的APK文件进行唯一签名,保证我们每次发布的版本的一致性(如自动更新不会因为版本不一致而无法安装)。

(7)签名过后的.apk文件其实就可以使用了,但是这时候的.apk文件太过杂乱,还需要Zipalign工具进行.apk文件的对其,减少内存,整理apk文件;

通过这七大步骤,一个apk文件就完整的生成出来了,那么我们知道apk文件是怎么生成的了,那么他又是怎么安装到我们的手机上呢?

android app的安装流程

android app的安装方式大致分为四种:

(1)系统应用安装---开机完成,没有安装界面;

(2)网络下载应用安装----通过mark应用完成,没有安装界面

(3)adb工具安装----没有安装界面

(4)第三方应用安装----通过sd卡中的apk文件安装,有安装界面,由Packageinstaller.apk应用处理完成及卸载

四大目录:

system/app-----系统自带的应用程序,获得adb root权限才能够访问

data /app-----用户程序安装目录,用户安装时将apk文件拷贝至此目录

data/data-----存放应用程序的数据

data/dalvik-cache----将apk中的dex文件安装到此目录下;

安装过程(用户程序):复制APK安装包到data/app目录下,解压并扫描安装包,把dex文件(Dalvik字节码)保存到dalvik-cache目录,并data/data目录下创建对应的应用数据目录。

安装步骤大致分为四步:

(1) 拷贝apk文件到指定目录
在Android系统中,apk安装文件是会被保存起来的,默认情况下,用户安装的apk首先会被拷贝到 /data/app 目录下。
/data/app目录是用户有权限访问的目录,在安装apk的时候会自动选择该目录存放用户安装的文件,而系统出厂的apk文件则被放到了 /system 分区下,包括 /system/app,/system/vendor/app,以及 /system/priv-app 等等,该分区只有Root权限的用户才能访问,这也就是为什么在没有Root手机之前,我们无法删除系统出厂的app的原因了。
(2) 解压apk,拷贝文件,创建应用的数据目录
为了加快app的启动速度,apk在安装的时候,会首先将app的可执行文件(dex)拷贝到 /data/dalvik-cache 目录,缓存起来。
然后,在/data/data/目录下创建应用程序的数据目录(以应用的包名命名),存放应用的相关数据,如数据库、xml文件、cache、二进制的so动态库等等。
(3) 解析apk的AndroidManifinest.xml文件
Android系统中,也有一个类似注册表的东西,用来记录当前所有安装的应用的基本信息,每次系统安装或者卸载了任何apk文件,都会更新这个文件。这个文件位于如下目录:
/data/system/packages.xml
系统在安装apk的过程中,会解析apk的AndroidManifinest.xml文件,提取出这个apk的重要信息写入到packages.xml文件中,这些信息包括:权限、应用包名、APK的安装位置、版本、userID等等。
由此,我们就知道了为啥一些应用市场和软件管理类的app能够很清楚地知道当前手机所安装的所有的app,以及这些app的详细信息了。
另外一件事就是Linux的用户Id和用户组Id,以便他可以获得合适的运行权限。
以上这些都是由PackageServiceManager完成的,下面我们会重点介绍PackageServiceManager。
(4) 显示快捷方式
这些应用程序只是相当于在PackageManagerService服务注册好了,如果我们想要在Android桌面上看到这些应用程序,还需要有一个Home应用程序,负责从PackageManagerService服务中把这些安装好的应用程序取出来,并以友好的方式在桌面上展现出来,例如以快捷图标的形式。在Android系统中,负责把系统中已经安装的应用程序在桌面中展现出来的Home应用程序就是Launcher了

接下来详细说说这几个步骤,再说之前,我们先弄清楚一个概念,在之前的app的启动流程中,我们说到,所有的app组件启动都是由AMS去实现的 ,那么安装当然也会有一个对应的服务,也就是PackageManagerService;

Android系统在启动的过程中,会启动一个应用程序管理服务PackageManagerService,这个服务负责扫描系统中特定的目录,找到里面的应用程序文件,即以Apk为后缀的文件,然后对这些文件进解析,得到应用程序的相关信息。应用程序管理服务PackageManagerService安装应用程序的过程,其实就是解析析应用程序配置文件AndroidManifest.xml的过程,并从里面得到得到应用程序的相关信息,例如得到应用程序的组件Activity、Service、Broadcast Receiver和Content Provider等信息,有了这些信息后,通过ActivityManagerService这个服务,我们就可以在系统中正常地使用这些应用程序了。应用程序管理服务PackageManagerService是系统启动的时候由SystemServer组件启动的,启后它就会执行应用程序安装的过程,因此,本文将从SystemServer启动PackageManagerService服务的过程开始分析系统中的应用程序安装的过程。

我们先分析SystemServer是怎样启动PackageManagerService的:
(1)由SystemServer.main方法开始
SystemServer组件是由Zygote进程负责启动的,启动的时候就会调用它的main函数,这个函数主要调用了JNI方法init1来做一些系统初始化的工作。
(2)SystemServer.init1()方法:(JNI方法)
这个函数很简单,只是调用了system_init函数来进一步执行操作。

(3)system_init()方法(c++方法)

这个函数首先会初始化SurfaceFlinger、SensorService、AudioFlinger、MediaPlayerService、CameraService和AudioPolicyService这几个服务,然后就通过系统全局唯一的AndroidRuntime实例变量runtime的callStatic来调用SystemServer的init2函数了。
(4)AndroidRuntime.callStatic方法(c++方法)

这个函数调用由参数className指定的java类的静态成员函数,这个静态成员函数是由参数methodName指定的。上面传进来的参数className的值为"com/android/server/SystemServer",而参数methodName的值为"init2",因此,接下来就会调用SystemServer类的init2函数了。
(5)SystemServer.init2()方法
这个函数创建了一个ServerThread线程,PackageManagerService服务就是这个线程中启动的了。这里调用了ServerThread实例thr的start函数之后,下面就会执行这个实例的run函数了。

(6)SystemServer.run()方法(PackageManagerService就是在这里启动的)

这个函数除了启动PackageManagerService服务之外,还启动了其它很多的服务

我们知道了PackageManagerService的启动流程之后,接下来就针对以上的四种情况一一进行分析,看看PMS是如何去进行app安装的;

(1)系统应用安装

A.扫描安装app

我们之前说过apk文件都是放在对应的文件目录下的,所以我们第一步做的事就是需要在对应文件夹中扫描对应的apk文件,PMS是通过调用它的scanDirLI方法:

private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
    final File[] files = dir.listFiles();
    if (ArrayUtils.isEmpty(files)) {
        Log.d(
  • 6
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值