多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
### 了解APK的打包流程吗,描述一下? Android的包文件APK分为两个部分:代码和资源,所以打包方面也分为资源打包和代码打包两个方面,这篇文章就来分析资源和代码的编译打包原理。 APK整体的的打包流程如下图所示: <img src="https://github.com/guoxiaoxing/android-open-source-project-analysis/raw/master/art/native/vm/apk_package_flow.png"/> 具体说来: 1. 通过AAPT工具进行资源文件(包括AndroidManifest.xml、布局文件、各种xml资源等)的打包,生成R.java文件。 2. 通过AIDL工具处理AIDL文件,生成相应的Java文件。 3. 通过Javac工具编译项目源码,生成Class文件。 4. 通过DX工具将所有的Class文件转换成DEX文件,该过程主要完成Java字节码转换成Dalvik字节码,压缩常量池以及清除冗余信息等工作。 5. 通过ApkBuilder工具将资源文件、DEX文件打包生成APK文件。 6. 利用KeyStore对生成的APK文件进行签名。 7. 如果是正式版的APK,还会利用ZipAlign工具进行对齐处理,对齐的过程就是将APK文件中所有的资源文件举例文件的起始距离都偏移4字节的整数倍,这样通过内存映射访问APK文件 的速度会更快。 ### 了解APK的安装流程吗,描述一下? APK的安装流程如下所示: <img src="https://github.com/guoxiaoxing/android-open-source-project-analysis/raw/master/art/app/package/apk_install_structure.png" width="600"/> 1. 复制APK到/data/app目录下,解压并扫描安装包。 2. 资源管理器解析APK里的资源文件。 3. 解析AndroidManifest文件,并在/data/data/目录下创建对应的应用数据目录。 4. 然后对dex文件进行优化,并保存在dalvik-cache目录下。 5. 将AndroidManifest文件解析出的四大组件信息注册到PackageManagerService中。 5. 安装完成后,发送广播。 ### 当点击一个应用图标以后,都发生了什么,描述一下这个过程? 点击应用图标后会去启动应用的LauncherActivity,如果LancerActivity所在的进程没有创建,还会创建新进程,整体的流程就是一个Activity的启动流程。 Activity的启动流程图(放大可查看)如下所示: <img src="https://github.com/guoxiaoxing/android-open-source-project-analysis/raw/master/art/app/component/activity_start_flow.png" /> 整个流程涉及的主要角色有: - Instrumentation: 监控应用与系统相关的交互行为。 - AMS:组件管理调度中心,什么都不干,但是什么都管。 - ActivityStarter:Activity启动的控制器,处理Intent与Flag对Activity启动的影响,具体说来有:1 寻找符合启动条件的Activity,如果有多个,让用户选择;2 校验启动参数的合法性;3 返回int参数,代表Activity是否启动成功。 - ActivityStackSupervisior:这个类的作用你从它的名字就可以看出来,它用来管理任务栈。 - ActivityStack:用来管理任务栈里的Activity。 - ActivityThread:最终干活的人,是ActivityThread的内部类,Activity、Service、BroadcastReceiver的启动、切换、调度等各种操作都在这个类里完成。 注:这里单独提一下ActivityStackSupervisior,这是高版本才有的类,它用来管理多个ActivityStack,早期的版本只有一个ActivityStack对应着手机屏幕,后来高版本支持多屏以后,就 有了多个ActivityStack,于是就引入了ActivityStackSupervisior用来管理多个ActivityStack。 整个流程主要涉及四个进程: - 调用者进程,如果是在桌面启动应用就是Launcher应用进程。 - ActivityManagerService等所在的System Server进程,该进程主要运行着系统服务组件。 - Zygote进程,该进程主要用来fork新进程。 - 新启动的应用进程,该进程就是用来承载应用运行的进程了,它也是应用的主线程(新创建的进程就是主线程),处理组件生命周期、界面绘制等相关事情。 有了以上的理解,整个流程可以概括如下: 1. 点击桌面应用图标,Launcher进程将启动Activity(MainActivity)的请求以Binder的方式发送给了AMS。 2. AMS接收到启动请求后,交付ActivityStarter处理Intent和Flag等信息,然后再交给ActivityStackSupervisior/ActivityStack 处理Activity进栈相关流程。同时以Socket方式请求Zygote进程fork新进程。 3. Zygote接收到新进程创建请求后fork出新进程。 4. 在新进程里创建ActivityThread对象,新创建的进程就是应用的主线程,在主线程里开启Looper消息循环,开始处理创建Activity。 5. ActivityThread利用ClassLoader去加载Activity、创建Activity实例,并回调Activity的onCreate()方法。这样便完成了Activity的启动。