《Android进阶解密》读后笔记

书封面

于2019年夏季阅读,主要基于系统源码,讲解Android一些常用的技术原理,对Android体系整体了解以及四大组件启动原理,虚拟机原理,热修复,插件化,内存优化等知识有了新的的认识。

第一章 Android系统架构

  • 应用层,应用框架层(提供开发所需的API),系统运行库及C++库(运行库包括ART虚拟机,java核心库),硬件抽象层(隐藏了特定平台的硬件接口细节,为操作系统提供虚拟硬件平台,使其具有硬件无关性),Linux内核层
  • 源码下载地址:http://pan.baidu.com/s/lngsZs
  • 源码整体架构:packages 存放应用程序包

第二章 系统启动

  • init进程启动:当按下电源键时,固化代码加载Bootloader,Bootloader又启动Linux内核,内核加载完第一件事就是启动init进程
  • init进程主要:1.创建和挂载启动所需的文件 2.初始化和启动属性服务 3.启动init.rc配置文件并启动Zygote进程
  • 关于zygote进程:在Android系统中,ART,应用程序进程,以及运行系统的关键服务SystemServer进程都由zygote进程来创建的(通过fork的形式进行创建),将他称为孵化器进程。由于zygote进程启动时会创建DVM或者ART,因此通过fork而创建的进程可以在内部获取一个ART实例副本;同时zygote进程创建服务端socket,等待AMS(ActivityManagerService)的请求来创建新的应用程序进程;以及zygote进程创建Java虚拟机并为java虚拟机注册JNI方法,通过JNI调用zygoteInit的Main方法进入zygote的java框架层
  • SystemServer进程被创建后:1.启动Binder线程池,这样就可以和其他进程进行通信 2.启动SystemServiceManager,其用于对系统的服务进行启动和生命周期管理 3.启动各种系统服务
  • 最后,launcher(桌面)被AMS启动后会将已安装应用的快捷图标显示到桌面上

第三章 应用程序进程的启动过程

  • AMS发送启动应用程序的请求,zygote接收到请求并创建应用程序进程,其中通过反射获得ActivityThread类并调用Main方法,这样应用程序创建完了并且运行了主线程的管理类
  • 应用程序启动的过程中会启动Binder线程池,ActivityThread Main方法被调用后创建主线程消息循环looper,这样可以使用消息处理机制

第四章 四大组件的启动过程

  • Activity的启动过程:launcher进程向AMS请求创建根Activity,AMS判断应用程序进程是否存在,存在则通过ApplicationThread创建根Activity,不存在则通过zygote先创建应用程序进程
  • 其他组件启动类似

第五章 上下文Context

  • context是应用程序环境信息的接口,使用场景分别是:1.使用context调用方法,如:启动Activity,访问资源等 2.调用方法时注入context
  • Activity,Service,Application都间接地继承自context,context是一个抽象类,它的内部定义了很多方法,以及静态变量,它的具体实现类:ContextImpl

第七章 理解ActivityManagerService

  • WindowManager管理window(view),通过调用WMS中的方法进行处理,这种关系类似于AMS,ActivityManager与Activity

第九章 JNI原理

  • JNI是Java本地接口,是Java与其他语言通信的桥梁,Native方法注册有:静态注册(即Java的Native方法通过指针来与JNI进行关联)和动态注册
  • JNIEnv是Native世界中Java环境的代表,通过JNIEnv指针就可以在Native世界中访问Java世界中的代码进行操作,它只在创建它的线程中有效
  • JNI引用类型 1.本地引用:JNIEnv提供的函数所返回的引用基本上都是本地引用,当Native函数返回时本地引用自动释放 2.全局引用:在Native函数返回时不会自动释放,因此需要手动释放,不受JVM管理 3.弱全局引用可以被gc回收

第十章 Java虚拟机

  • Java虚拟机上能运行的程序与语言无关,无论任何语言只要能编译成class文件就可以被Java虚拟机识别并运行
  • Java虚拟机的启动就是通过引导类加载器创建一个初始类来完成,类加载器是使用平台相关的底层C/C++语言实现
  • Java的内存区域分别为:程序计数器,Java虚拟机栈,本地方法栈,Java堆和方法区;如果线程请求分配的栈容量超过Java虚拟机所允许的最大容量,Java虚拟机会抛出StackOverflowError;如果java虚拟机可以动态扩容,但是扩展时无法申请到足够的内存则会抛出OutOfMemoryError异常
  • gc主要两个工作:1.内存的划分和分配 2.对垃圾进行回收;gc主要采用分代回收算法回收垃圾,Java堆作为gc主要管理的区域,被细分为新生代和老年代
  • Java对象在虚拟机中的生命周期:1.创建阶段 2.应用阶段 3.不可见阶段 4.不可达阶段 5.收集阶段 6.终结阶段 7.对象空间重新分配阶段
  • 垃圾收集算法:1.标记——清楚算法 2.复制算法(把内存空间划分为两个相等的区域,每次只使用一个区域,在收集时遍历使用区域,把存活复制到另一个区域,最后将当前使用的区域可回收的对象进行回收)

第十二章 ClassLoader类加载器

  • 类加载器查找class文件采用的是双亲委托模式(首先判断该class是否已经加载,如果没有则不是自身去查找而是委托给父加载器进行查找,这样依次递归,直到委托到顶层的Bootstrap ClassLoader,如果Bootstrap class找到了就返回,没有找到,则继续依次向下查找,如果还没有找到则会交由自身去查找)
  • Android中的ClassLoader也是采用双亲委托模式查找class,不同的是它们加载的不再是class或jar文件,而是dex文件

第十三章 热修复原理

  • 热修复主要有:代码修复,资源修复,so修复;多种热修复框架参考了InstantRun的资源修复原理,InstantRun并不是Android源码,需要反编译获取
  • InstantRun 资源热修复主要有连个步骤:1.创建新的AssetManager,通过反射调用addAsserPath方法加载外部资源,这样新建的AssetManager就含有了外部资源 2.将AssetManager类型的mAssets字段的引用全部替换为新创建的AssetManager
  • 代码修复主要有类加载方案,底层替换方案,InstantRun方案。1.类加载方案基于dex分包方案,类加载方案需要重新启动APP后让ClassLoader重新加载新的类,重启的原因是类是无法被卸载的,通过修改Element数组使加载新的dex;2.底层替换方案:替换ArtMethod结构体中的字段或者整个ArtMethod结构体,直接替换方法,可以做到立即生效不需要重启;3.可以借鉴InstantantRun的ASM,ASM是一个Java字节码操作框架,能够动态生成类或者增强现有类的功能,ASM可以直接产生class文件,也可以在类加载到虚拟机之前动态改变类的行为
  • So修复方案:1.将so补丁插入到NativelibraryElement数组的前部,让So补丁的路径先被返回和加载 2.调用System的load方法来接管So的加载入口

第十四章 Hook技术

  • Hook可以是一个方法或者一个对象,它像一个钩子一样挂在对象A和对象B之间,当对象A调用对象B之前做一些处理(比如修改方法的参数和返回值)起到欺上瞒下的作用,与其说Hook是钩子,不如说劫持更贴切些
  • Hook技术的分类:1.Hook Java 主要通过反射和代理来实现,应用于SDK开发环境中修改Java代码 2.Hook Native应用于NDK开发环境中修改Native代码 3.通过反射和代理实现,只能Hook当前的应用程序进程,通过Hook框架来实现,比如Xposed,可以实现全局Hook,但是需要root
  • 代理模式也叫委托模式,为其他对象提供一种代理可以控制对这个对象的访问,动态代理则是在代码运行时通过反射动态生成代理类的对象,并确定到底代理谁。

第十五章 插件化原理

  • 热修复技术,插件化技术都属于动态加载技术(动态加载一些程序中原本不存在的可执行文件并运行这些文件里的代码逻辑,其中热修复技术主要用来修复Bug,插件化技术用于解决应用越来越庞大以及功能模块的解耦)
  • 插件化的客户端由宿主和插件两个部分组成,宿主指安装到手机中的apk,插件一般是指经过处理过的apk,so,dex文件等,插件可被宿主加载;插件化的定义:将一个应用按照插件进行改造的过程就叫插件化
  • 四大组件是插件化技术的核心知识点,主流的插件化多采用Hook技术实现
  • 启动插件Activity的原理:主要的方案是先在AndroidMainfest.xml文件中注册的Activity占坑,用来通过AMS校验,接着用插件化Activity替换占坑的Activity
  • Service的插件化的要点是保证它的优先级,当启动插件Service时就会先启动代理Service,当这个代理Service运行起来之后,在它的OnStartCommand等方法中进行分发,执行插件TargetService的OnCreate等方法

第十六章 绘制优化

  • 绘制原理:View的绘制流程有3个步骤,分别是:measure,layout,draw,它们主要运行在系统的应用框架层,而真正将数据渲染到屏幕上的是系统Nativie层的SurfaceFlings服务来完成的;Android系统每隔16ms发出VSYNS信号,触发对UI进行渲染,如果每次都成功,就能够达到流程的画面所需要的60fps,VSYNC是一种定时中断,一旦受到VSYNC信号,CPU就开始处理各种帧数据,如果某个操作超过16ms则无法正常渲染,会发生丢帧
  • Profile GPU Rendering 在开发者中打开,显示应用渲染的情况,Systrace是性能数据采样和分析工具;TraceView是Android SDK中自带的数据采集分析工具
  • 布局优化工具:Hierarchy viewer用来检查布局嵌套和绘制的时间,Android Lint进行静态检查
  • 布局优化方法:1.合理运用布局 2.Include 3.Merger去除多余的曾经 4.使用ViewStub提高加载速度 5.避免CPU过度绘制

第十七章 内存优化

  • 内存监视工具:1.Mermory Monitor 2.Allocation Tracker(显示对象类型,大小,时间)3.Heep Dump 查看不同数据类型在内存中的使用情况 4.内存泄漏分析:Mat,LeakCanary
  • 频繁多次打开关闭界面观察内存变化

推荐阅读更多精彩内容