Android APP编译流程

Android Gradle plugin的具体流程

  • 首先上一张官方的图:
    在这里插入图片描述
  1. 首先通过aapt打包res资源文件,生成R.java、resources.arsc和res文件(二进制&非二进制保持原来的代码)
  2. 处理.aidl文件,生成对应的Java接口文件
  3. 通过Java Compile编译R.java、java接口文件,生成.class文件
  4. 通过dex命令,将.class文件和第三方库中的.class文件处理生成classes.dex文件
  5. 通过apkbuilder将aapt生成的CompiledResources和其他资源文件以及classes.dex文件打包生成apk
  6. 通过Jarsigner工具,对上面的apk进行debug或者release签名
  7. 通过zipalign工具,将签名后的apk进行对齐处理
  • 构建流程图:
    在这里插入图片描述
    1.编译器将源代码转换成dex文件(包括Android设备上的字节码),将所有的其他内容转换成已编译资源
    2.APK打包器将DEX文件和已编译资源合成单个APK,不过,必须先签署APK,才能将应用安装并部署到Android设备上
    3.APK打包器使用调试或发布密钥签署库签署APK(分为debug和release版本)
    4.在生成最终的APK之前,打包器会使用zipalign工具对应用进行优化,减少其在设备上运行时的内存占用

构建

  • 主要使用的android gradle plugin是com.androi.application 和com.android.library,两者对应的类分别是com.android.build.gradle.AppPlugin,而com.android.library插件对应的类是com.android.build.gradle.LibraryPlugin
  • 函数执行流程
apply()->configureProject()->configureExtension()->createTasks()->createAndroidTasks()

Gradle生命周期

  • 初始化阶段,执行settings.gradle,并将每个Project内的build.gradle转化为project对象

  • Configration阶段,配置对应的Project对象,执行build.gradle中的代码,Configuration阶段完结后,整个build的project以及内部的Task关系就确定了,Configuration会建立一个有向图来描述Task之间的依赖关系

  • 执行阶段:执行相应的task

  • 每个生命周期都可以进行hook

  • 可以在 setting中设置不同的gradle,本地和远端用不同的也可以引入不同的moudle

  • 可以在build.gradle中定义各种变体,可以设置使用本地moudle或者使用远端的moudle

  • 可以在任意的Task前插入自己的Task, 编译时增删java代码,修改字节码等,各种插件,hook代码都是在这里进行执行的,还可以制作模块热插拔,优化编译速度等

R文件引用到真正的资源文件

  • aapt工具对于每个资源文件生成了位移的ID,这些ID保存在R.java文件中
//资源ID是一个4字节表示的无符号整数,在R.java文件中用16进制表示,其中,最高的1字节表示Package ID, 次高1个字节表示TypeID, 最低2字节表示Entry ID
public final class R {
    public static final class anim {
        public static final int abc_fade_in=0x7f050000;
        public static final int abc_fade_out=0x7f050001;
        public static final int abc_grow_fade_in_from_bottom=0x7f050002;
      
    }
    public static final class animator {
        public static final int design_appbar_state_list_animator=0x7f060000;
        public static final int slide_in_left=0x7f060001;
        public static final int slide_out_left=0x7f060002;
    }
  • aapt在生成ID的同时还生成了一个resources.arsc文件,相当于一个资源索引表,该表的key是资源ID, value是资源在apk中的路径
  • 所以通过R.java和resources.arsc文件就可以引用到实际的资源文件

对齐优化

  • 在上面的打包过程中涉及到对齐这个词,在编译原理中学到过内存对齐,在这里如果每个资源的开始位置都是上一个资源之后的4 * n字节,那么访问下一个资源就不需要遍历,直接跳至4* n字节处并判断资源的时间戳即可(数组的随机访问比链表快)

猜你喜欢

转载自blog.csdn.net/qq_39424143/article/details/95094949