Gradle Transform API :直接修改 class 文件

首先,我要说的是,我没想到写这篇文章会遇到那么多的难点。其次在写这篇文章的时候,我还是处于一个半吊子的状态,但是我想应该还是会比现有的大部分blog要好的多。我几乎将Google到的索引到的前几页文章全部看了一遍,但是大部分都是相同的内容,就只有一篇我印象比较深,写的比较全面,但是我仍然还有很多疑问。下面的文章我会提出我自己在学习这个知识点时想要问的问题,有些问题我可以自己解答,但是有些还是摸棱...
摘要由CSDN通过智能技术生成

首先,我要说的是,我没想到写这篇文章会遇到那么多的难点。其次在写这篇文章的时候,我还是处于一个半吊子的状态,但是我想应该还是会比现有的大部分blog要好的多。我几乎将Google到的索引到的前几页文章全部看了一遍,但是大部分都是相同的内容,就只有一篇我印象比较深,写的比较全面,但是我仍然还有很多疑问。

下面的文章我会提出我自己在学习这个知识点时想要问的问题,有些问题我可以自己解答,但是有些还是摸棱两可。

首先列出阅读这篇文章所需要的基础知识,如果你连这些都没有掌握的话,就不建议往下看了,会很痛苦,除非你只是想了解一下。

  • Goorvy 基本语法
  • Gradle 构建
  • ASM

前两个知识点有一个快速掌握的方法,阅读这个 PDF 文件,写的还是非常不错的,我花了一个小时看完,我看的比较快,因为我看过《Gradle权威指南》这本书。

好了,从这里开始,我就当你已经掌握了上面的相关知识点。

Gradle 工作流程

Gradle 是一个框架,它定义一套自己的游戏规则。我们要玩转 Gradle,必须要遵守它设计的规则。

下面我们来讲讲 Gradle 的基本组件:

  • Gradle 中,每一个待编译的工程都叫一个 Project。每一个 Project 在构建的时候都包含一系列的 Task。比如
    一个 Android APK 的编译可能包含:Java 源码编译 Task、资源编译 Task、JNI 编译 Task、lint 检查 Task、打包生成 APK 的 Task、签名 Task 等。
  • 一个 Project 到底包含多少个 Task,其实是由编译脚本指定的插件决定。插件是什么呢?插件就是用来定义 Task,并具体执行这些 Task 的东西。

Gradle 作为框架,它负责定义流程和规则,而具体的编译工作则是通过插件的方式来完成的。比如编译 Java 有 Java 插件,编译 Groovy 有 Groovy 插件,编译 Android APP 有 Android APP 插件,编译 Android Library 有 Android Library 插件。好了,到现在为止,你知道 Gradle 中每一个待编译的工程都是一个 Project,一个具体的编译过程是由一个一个的 Task 来定义和执行的。

在这里插入图片描述

在 Android Stuido 中,每个 moudle 都有自己的 build.gradle 文件。在构建的时候,每一个 build.gradle 文件都会转换成一个 Project 对象

一个 Project 会包含若干 Tasks。另外,由于 Project 对应具体的工程,所以需要为 Project 加载所需要的插件,比如:为 Java 工程加载 Java 插件,为 Android 工程加载 Android 插件。

在这里插入图片描述

这里就为该工程加载了 3 个插件。一般的插件可以直接使用,但是有的插件可能还需要配置扩展。

在这里插入图片描述

如上图所示,这是属于 com.android.application 插件的一个 android 扩展。在这里我们就可以配置该扩展的一些属性。

了解了这些,我们继续。

Gradle 工作包含三个阶段:

  1. 首先是Initiliazation阶段:对我们前面的 multi-project build 而言,就是执行 settings.gradle。
  2. 然后是 Configration 阶段:Configration 阶段的目标是解析每个 project 中的 build.gradle。在这两个阶段之间,我们可以加一些定制化的Hook。这当然是通过 API 来添加的。
  3. Configuration 阶段完了后,整个 build 的 project 以及内部的 Task 关系就确定了。前面说过,一个Project 包含很多 Task,每个 Task 之间有依赖关系。Configuration 会建立一个有向图来描述 Task 之间的依赖关系。所以,我们可以添加一个 HOOK,即当 Task 关系图建立好后,执行一些操作。
  4. 最后一个阶段就是执行任务了。

Transform API 为什么可以修改 class 文件

我们知道,一个 project 的构建是由很多 task 组成的,而这些 task 是有依赖关系的。我们结合一下 App 的打包流程来看一下,各个 task 是发生在什么时候。

在 App 打包的时候,首先需要先将 java 文件编译为 class 文件(这里不关心一些其他的 AIDL 之类的),然后将 jar 与 class 文件达成 dex 文件。由于工程是 Gradle 构建的,Gradle 的构建是基于 Task 的,所以这些编译java文件,打包 class 文件都是在 task 中执行的。

在构建的过程中,这些 Task 都是由 TaskManager 管理的:

com.android.build.gradle.internal.TaskManager#createCompileTask

    protected void createCompileTask(@NonNull VariantScope variantScope) {
   
        TaskProvider<? extends JavaCompile> javacTask = createJavacTask(variantScope);
        addJavacClassesStream(variantScope);
        setJavaCompilerTask(javacTask, variantScope);
        createPostCompilationTasks(variantScope);
    }

这里是先执行了 javac 的编译任务,然后执行 post 编译任务。

com.android.build.gradle.internal.TaskManager#createPostCompilationTasks

    public void createPostCompilationTasks(
            @NonNull TaskFactory tasks,
            @NonNull final VariantScope variantScope) {
   
        ...
        // ----- External Transforms -----
        // 添加自定义的 Transform
        List<Transform> customTransforms = extension.getTransforms();
        List<List<Object>> customTransformsDependencies = extension.getTransformsDependencies();

        for (int i = 0, count = customTransforms.size() ; i < count ; i++) {
   
            Transform transform = customTransforms.get(i);
            AndroidTask<TransformTask> task = transformManager
                    .addTransform(tasks, variantScope, transform);
            ...
        }
        ...
        // ----- Minify next -----
        // minifyEnabled 为 true 表示开启混淆
        // 添加 Proguard Transform
        if (isMinifyEnabled) {
   
            boolean outputToJarFile = isMultiDexEnabled && isLegacyMultiDexMode;
            createMinifyTransform(tasks, variantScope, outputToJarFile);
        }
        ...
        
        // non Library test are running as native multi-dex
        if (isMultiDexEnabled 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值