### 了解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的启动。
- Android面试题集
- Android系统架构图
- Activity与Service通信
- Service的生命周期与启动方法
- 广播
- ContentProvider、ContentResolver与ContentObserver之间的关系
- 关于Fragment的问题
- Android里的Intent传递的数据限制
- Android的事件分发机制
- View的绘制原理
- APK的打包流程
- BroadcastReceiver与LocalBroadcastReceiver
- Handler
- Android Binder机制
- Activity的生命周期
- Activity的通信方式
- Android应用里的Context对象
- 进程和Application的生命周期
- 内存泄漏
- Android的几种进程
- SharePreference性能优化
- SQLite升级
- 进程保护
- 序列化
- 计算一个Bitmap占用内存
- 内存缓存和磁盘缓存
- PathClassLoader与DexClassLoader
- WebView优化
- JNI
- 插件化和热修复
- 性能优化
- 防止过度绘制,做布局优化
- 提交代码质量
- 64k问题
- MVC、MVP与MVVM之间的对比分析
- Android中高级面试题
- Activity生命周期
- onStart()与onResume()有什么区别
- Activity启动流程
- Android类加载器
- Android消息机制
- Looper.loop()为什么不会阻塞主线程
- IdleHandler (闲时机制)
- 同步屏障机制(sync barrier)
- View的绘制原理
- 什么是MeasureSpec
- getWidth()方法和getMeasureWidth()区别
- requestLayout,invalidate,postInvalidate区别与联系
- Binder机制,共享内存实现原理
- 序列化的方式
- Fragment的懒加载实现
- RecyclerView与ListView(缓存原理,区别联系,优缺点)
- Android两种虚拟机区别与联系
- adb常用命令行
- apk打包流程
- apk安装流程
- apk瘦身
- HTTP缓存机制
- 组件化
- okhttp原理
- Retrofit的实现与原理
- RxLifecycle原理
- 类的加载机制
- 什么时候发生类初始化
- 双亲委派模型
- 为什么使用双亲委托模型
- HashMap原理,Hash冲突
- 什么是Fail-Fast机制
- Java多线程中调用wait() 和 sleep()方法有什么不同?
- volatile的作用和原理
- 一个int变量,用volatile修饰,多线程去操作++,线程安全吗?
- 那如何才能保证i++线程安全?
- CAS实现原子操作会出现什么问题?
- synchronized
- 偏向锁
- 轻量级锁
- 线程池
- 假如有n个网络线程,你需要当n个网络线程完成之后,再去做数据处理,你会怎么解决?
- Java中interrupted 和 isInterruptedd方法的区别?
- 懒汉式单例的同步问题
- 什么是ThreadLocal
- 什么是数据竞争
- Java内存模型(Java Memory Model JMM)
- Java内存区域
- 判断对象是否需要回收的方法
- 引用类型
- 垃圾收集算法
- 内存分配策略