概述
又开始了一个新的系列,这个系列学习Gradle,目标就是彻底理解Gradle,主要还是做下自己理解的笔记,防止忘记
Gradle学习系列(五):Gradle Transform
Gradle学习系列(七):Android Gradle Plugin 源码解析
阅读前准备
首先务必要先阅读这篇文章Gradle学习系列(三):Gradle插件,这个是基础,自己先尝试自定义一个插件,然后在看源码会更简单一些
准备源码
这里有一个取巧的办法查看源码,首先建立一个java libary ,然后更改build为下面的代码
apply plugin: 'groovy'  //必须
apply plugin: 'maven'  //要想发布到Maven,此插件必须使用
dependencies {
    implementation gradleApi() //必须
    implementation localGroovy() //必须
    implementation 'com.android.tools.build:gradle:3.4.1'
}
repositories {
    mavenCentral() //必须
}
复制代码build一下,就可以在External Libraries看到gradle源码

开始阅读源码
首先找什么看呢? 当然找我们经常用的插件,看他的源码实现,我们经常用的插件是这个
apply plugin: 'com.android.application'
复制代码如何找这个插件的源码,这个就需要插件的基础知识了,不知道的返回去看Gradle学习系列(三):Gradle插件

直接看到实现类是AppPlugin,再继续看下AppPlugin的源码
public class AppPlugin extends AbstractAppPlugin {
    @Inject
    public AppPlugin(ToolingModelBuilderRegistry registry) {
        super(registry, true /*isBaseApplication*/);
    }
    ....
    @Override
    @NonNull
    protected Class<? extends AppExtension> getExtensionClass() {
        return BaseAppModuleExtension.class;
    }
}
复制代码我们知道插件类需要实现Plugin<Project>,而AppPlugin继承自AbstractAppPlugin所有继续向下找
public abstract class AbstractAppPlugin extends BasePlugin<AppExtensionImpl> {
    private final boolean isBaseApplication;
    ...
    @NonNull
    @Override
    protected BaseExtension createExtension(
            @NonNull Project project,
            @NonNull ProjectOptions projectOptions,
            @NonNull GlobalScope globalScope,
            @NonNull SdkHandler sdkHandler,
            @NonNull NamedDomainObjectContainer<BuildType> buildTypeContainer,
            @NonNull NamedDomainObjectContainer<ProductFlavor> productFlavorContainer,
            @NonNull NamedDomainObjectContainer<SigningConfig> signingConfigContainer,
            @NonNull NamedDomainObjectContainer<BaseVariantOutput> buildOutputs,
            @NonNull SourceSetManager sourceSetManager,
            @NonNull ExtraModelInfo extraModelInfo) {
        return project.getExtensions()
                .create(
                        "android",
                        getExtensionClass(),
                        project,
                        projectOptions,
                        globalScope,
                        sdkHandler,
                        buildTypeContainer,
                        productFlavorContainer,
                        signingConfigContainer,
                        buildOutputs,
                        sourceSetManager,
                        extraModelInfo,
                        isBaseApplication);
    }
}
复制代码AbstractAppPlugin继承自BasePlugin,继续向下看
public abstract class BasePlugin<E extends BaseExtension2>
        implements Plugin<Project>, ToolingRegistryProvider {
    ....
    @Override
    public final void apply(@NonNull Project project) {
        CrashReporting.runAction(
                () -> {
                    basePluginApply(project);
                    pluginSpecificApply(project);
                });
    }
复制代码我们看到BasePlugin实现了Plugin<Project>所以这个就是最终的一个实现类,我们看下apply这个里面是最主要的实现,里面调用了basePluginApply(project)方法,我们看一下源码
 private void basePluginApply(@NonNull Project project) {
        //上边坐了一些初始化操
        ...
        if (!projectOptions.get(BooleanOption.ENABLE_NEW_DSL_AND_API)) {
            //这里是最主要的几个方法
            threadRecorder.record(
                    ExecutionType.BASE_PLUGIN_PROJECT_CONFIGURE,
                    project.getPath(),
                    null,
                    //配置项目
                    this::configureProject);
            threadRecorder.record(
                    ExecutionType.BASE_PLUGIN_PROJECT_BASE_EXTENSION_CREATION,
                    project.getPath(),
                    null,
                    //配置扩展
                    this::configureExtension);
            threadRecorder.record(
                    ExecutionType.BASE_PLUGIN_PROJECT_TASKS_CREATION,
                    project.getPath(),
                    null,
                    //创建任务
                    this::createTasks);
        } 
    }
复制代码下面我们一次看一下这几个方法
configureProject
 private void configureProject() {
        ...
        //为Gradle插件处理所有的事情的sdk。每个项目大约有一个实例
        sdkHandler = new SdkHandler(project, getLogger());
        //创建AndroidBuilder,这是主构建器类。它得到了所有用于处理构建的数据(例如{@link
        //DefaultProductFlavor}、{@link DefaultBuildType}和依赖项)
        AndroidBuilder androidBuilder =
                new AndroidBuilder(
                        project == project.getRootProject() ? project.getName() : project.getPath(),
                        creator,
                        new GradleProcessExecutor(project),
                        new GradleJavaProcessExecutor(project),
                        extraModelInfo.getSyncIssueHandler(),
                        extraModelInfo.getMessageReceiver(),
                        getLogger());
        //创建dataBindingBuilder,
        dataBindingBuilder = new DataBindingBuilder();
        dataBindingBuilder.setPrintMachineReadableOutput(
                SyncOptions.getErrorFormatMode(projectOptions) == ErrorFormatMode.MACHINE_PARSABLE);
        ...
        // Enforce minimum versions of certain plugins
        //强制使用不低于当前支持插件的最小版本
        GradlePluginUtils.enforceMinimumVersionsOfPlugins(
                project, androidBuilder.getIssueReporter());
        // Apply the Java plugin
        //应用java插件
        project.getPlugins().apply(JavaBasePlugin.class);
        //创建构建缓存,如果启用,构建缓存目录将设置为用户定义的目录,如果用户定义的目录没有提供,则为默认目录
        @Nullable
        FileCache buildCache = BuildCacheUtils.createBuildCacheIfEnabled(project, projectOptions);
        //创建全局作用域,主要是为Android plugin 保存数据
        globalScope =
                new GlobalScope(
                        project,
                        new ProjectWrapper(project),
                        projectOptions,
                        dslScope,
                        androidBuilder,
                        sdkHandler,
                        registry,
                        buildCache);
        //找到assemble Task 添加描述
        project.getTasks()
                .getByName("assemble")
                .setDescription(
                        "Assembles all variants of all applications and secondary packages.");
        //执行时回调。这是在整个构建完成后调用的(不是在当前项目完成后)。
        //这个会被每个(android)项目调用,所以这个应该支持被调用2+次。  
        gradle.addBuildListener(
                new BuildListener() {
                    @Override
                    public void buildStarted(@NonNull Gradle gradle) {}
                    @Override
                    public void settingsEvaluated(@NonNull Settings settings) {}
                    @Override
                    public void projectsLoaded(@NonNull Gradle gradle) {}
                    @Override
                    public void projectsEvaluated(@NonNull Gradle gradle) {}
                    @Override
                    public void buildFinished(@NonNull BuildResult buildResult) {
                        // Do not run buildFinished for included project in composite build.
                        if (buildResult.getGradle().getParent() != null) {
                            return;
                        }
                        ModelBuilder.clearCaches();
                        sdkHandler.unload();
                        threadRecorder.record(
                                ExecutionType.BASE_PLUGIN_BUILD_FINISHED,
                                project.getPath(),
                                null,
                                () -> {
                                    WorkerActionServiceRegistry.INSTANCE
                                            .shutdownAllRegisteredServices(
                                                    ForkJoinPool.commonPool());
                                    Main.clearInternTables();
                                });
                        DeprecationReporterImpl.Companion.clean();
                    }
                });
    }
复制代码这个方法主要做了一下几件事
- 创建SdkHandler,为Gradle插件处理所有的事情的sdk。每个项目大约有一个实例
- 创建AndroidBuilder,这是主构建器类。它得到了所有用于处理构建的数据(例如{@linkDefaultProductFlavor}、{@link DefaultBuildType}和依赖项)
- 创建DataBindingBuilder
- 强制使用不低于当前支持插件的最小版本
- 应用java插件
- 创建构建缓存,如果启用,构建缓存目录将设置为用户定义的目录,如果用户定义的目录没有提供,则为默认目录
- 创建全局作用域,主要是为Android plugin 保存数据
- 找到assemble Task 添加描述
- 监听构建完成回调,做一些清尾工作
configureExtension 配置扩展
什么是扩展我就不再重复说了,看我之前博客去
   private void configureExtension() {
        //是不是看起来很熟悉,是的这就是配置不固定数量的扩展,这个是配置的BuildType,
        //不懂的看之前博客,所以BuildType中才可以自定义名字
        final NamedDomainObjectContainer<BuildType> buildTypeContainer =
                project.container(
                        BuildType.class,
                        new BuildTypeFactory(
                                objectFactory,
                                project,
                                extraModelInfo.getSyncIssueHandler(),
                                extraModelInfo.getDeprecationReporter()));
        //一样的道理配置不定项扩展ProductFlavor
        final NamedDomainObjectContainer<ProductFlavor> productFlavorContainer =
                project.container(
                        ProductFlavor.class,
                        new ProductFlavorFactory(
                                objectFactory,
                                project,
                                extraModelInfo.getDeprecationReporter(),
                                project.getLogger()));
        //一样的道理配置不定项扩展SigningConfig
        final NamedDomainObjectContainer<SigningConfig> signingConfigContainer =
                project.container(
                        SigningConfig.class,
                        new SigningConfigFactory(
                                objectFactory,
                                GradleKeystoreHelper.getDefaultDebugKeystoreLocation()));
        //一样的道理配置不定项扩展BaseVariantOutput
        final NamedDomainObjectContainer<BaseVariantOutput> buildOutputs =
                project.container(BaseVariantOutput.class);
        project.getExtensions().add("buildOutputs", buildOutputs);
        sourceSetManager =
                new SourceSetManager(
                        project,
                        isPackagePublished(),
                        globalScope.getDslScope(),
                        new DelayedActionsExecutor());
        //这个就是创建 android 扩展
        extension =
                createExtension(
                        project,
                        projectOptions,
                        globalScope,
                        sdkHandler,
                        buildTypeContainer,
                        productFlavorContainer,
                        signingConfigContainer,
                        buildOutputs,
                        sourceSetManager,
                        extraModelInfo);
        globalScope.setExtension(extension);
        variantFactory = createVariantFactory(globalScope, extension);
        //创建TaskManager,任务管理类
        taskManager =
                createTaskManager(
                        globalScope,
                        project,
                        projectOptions,
                        dataBindingBuilder,
                        extension,
                        sdkHandler,
                        variantFactory,
                        registry,
                        threadRecorder);
        //创建VariantManager,变体管理类
        variantManager =
                new VariantManager(
                        globalScope,
                        project,
                        projectOptions,
                        extension,
                        variantFactory,
                        taskManager,
                        sourceSetManager,
                        threadRecorder);
        registerModels(registry, globalScope, variantManager, extension, extraModelInfo);
        ...
        //按顺序依次创建 signingConfig debug、buildType debug、buildType releas类型的 DSL。
        // create default Objects, signingConfig first as its used by the BuildTypes.
        variantFactory.createDefaultComponents(
                buildTypeContainer, productFlavorContainer, signingConfigContainer);
    }
复制代码这个方法主要是做了一下几件事
- 
配置不定项扩展BuildType,ProductFlavor,SigningConfig,BaseVariantOutput buildTypes { release {} debug {} vip {} aaa {} } flavorDimensions "xiaomi", "huawei" productFlavors { JD { dimension("xiaomi") } TAO { dimension("xiaomi") } PIN { dimension("huawei") } } 复制代码所以我们才可以这样自定义每一项的名字,可以配置多项 
- 
创建android 扩展,也就是我们最常用的 android { compileSdkVersion 29 ... } 复制代码
- 
创建TaskManager,任务管理类 
- 
创建VariantManager,变体管理类 
- 
按顺序依次创建 signingConfig debug、buildType debug、buildType releas类型的 DSL。 
createTasks
  private void createTasks() {
        threadRecorder.record(
                ExecutionType.TASK_MANAGER_CREATE_TASKS,
                project.getPath(),
                null,
                () -> taskManager.createTasksBeforeEvaluate());
        project.afterEvaluate(
                CrashReporting.afterEvaluate(
                        p -> {
                            sourceSetManager.runBuildableArtifactsActions();
                            threadRecorder.record(
                                    ExecutionType.BASE_PLUGIN_CREATE_ANDROID_TASKS,
                                    project.getPath(),
                                    null,
                                    this::createAndroidTasks);
                        }));
    }
复制代码这个方法分为俩个阶段,第一个是在BeforeEvaluate()创建createTasks,第二个是afterEvaluate之后createAndroidTasks
因为AndroidTask需要依赖配置项的配置才能生成任务,所以是在afterEvaluate之后创建,beforeEvaluate创建的任务跟我们编译没太大关系,所以重点分析afterEvaluate之后createAndroidTasks
createAndroidTasks
  final void createAndroidTasks() {
       ...
        //创建应用Task
        List<VariantScope> variantScopes = variantManager.createAndroidTasks();
    }
复制代码接下来我们看一下variantManager的createAndroidTasks
 public List<VariantScope> createAndroidTasks() {
        variantFactory.validateModel(this);
        variantFactory.preVariantWork(project);
        //判断是否为空,如果为空就为这个list填充
        if (variantScopes.isEmpty()) {
            populateVariantDataList();
        }
        // Create top level test tasks.
        //创建项目级别的测试task
        taskManager.createTopLevelTestTasks(!productFlavors.isEmpty());
        //遍历variantScopes,然后为每一个VariantData创建Task
        for (final VariantScope variantScope : variantScopes) {
            createTasksForVariantData(variantScope);
        }
        //创建报告相关的task
        taskManager.createSourceSetArtifactReportTask(globalScope);
        taskManager.createReportTasks(variantScopes);
        return variantScopes;
    }
复制代码接下主要看下createTasksForVariantData方法
  public void createTasksForVariantData(final VariantScope variantScope) {
        final BaseVariantData variantData = variantScope.getVariantData();
        final VariantType variantType = variantData.getType();
        final GradleVariantConfiguration variantConfig = variantScope.getVariantConfiguration();
        //创建Assemble Task
        taskManager.createAssembleTask(variantData);
        if (variantType.isBaseModule()) {
            taskManager.createBundleTask(variantData);
        }
        if (variantType.isTestComponent()) {
           ...
        } else {
            //如果不是一个 Test moudle,则会调用 ApplicationTaskManager 的 createTasksForVariantScope 方法。
            taskManager.createTasksForVariantScope(variantScope);
        }
    }
复制代码这个最终会调用ApplicationTaskManager 的 createTasksForVariantScope ,在这个方法内部创建一系列适用于应用构建的Task
  @Override
    public void createTasksForVariantScope(@NonNull final VariantScope variantScope) {
        createAnchorTasks(variantScope);
        createCheckManifestTask(variantScope);
        handleMicroApp(variantScope);
        // Create all current streams (dependencies mostly at this point)
        createDependencyStreams(variantScope);
        // Add a task to publish the applicationId.
        createApplicationIdWriterTask(variantScope);
        // Add a task to process the manifest(s)
        // Add a task to create the res values
        // Add a task to compile renderscript files.
        // Add a task to merge the resource folders
        // Add tasks to compile shader
        // Add a task to merge the asset folders
        // Add a task to create the BuildConfig class
        // Add a task to process the Android Resources and generate source files
        // Add a task to process the java resources
        // Add external native build tasks
        // Add a task to merge the jni libs folders
        // Add feature related tasks if necessary
        // Add data binding tasks if enabled
    
        // Add a compile task   
    }
复制代码由于代码太长这里只留下了注释,注释也很清楚这里生成了一些列的 compileXXX、generateXXX、processXXX、mergeXXX的任务,这一系列的Task就是构建一个可运行完整APK所需要的偶有Task
有关Task的一些基础知识可以参考我这篇文章Gradle学习系列(二):Gradle核心探索
如何查看每个Task的实现类?
我们拿这个举例子
  createCheckManifestTask(variantScope);
复制代码我们跟进去源码看一下
 public void createCheckManifestTask(@NonNull VariantScope scope) {
        taskFactory.register(getCheckManifestConfig(scope));
    }
复制代码发现调用了taskFactory.register,继续跟下源码,进入TaskFactoryImpl的register
  override fun <T : Task> register(creationAction: TaskCreationAction<T>): TaskProvider<T> =
        taskContainer.registerTask(creationAction, null, null, null)
复制代码再继续跟进源码
fun <T : Task> TaskContainer.registerTask(
    creationAction: TaskCreationAction<T>,
    secondaryPreConfigAction: PreConfigAction? = null,
    secondaryAction: TaskConfigAction<in T>? = null,
    secondaryProviderCallback: TaskProviderCallback<T>? = null
): TaskProvider<T> {
    val actionWrapper = TaskAction(creationAction, secondaryPreConfigAction, secondaryAction, secondaryProviderCallback)
    return this.register(creationAction.name, creationAction.type, actionWrapper)
        .also { provider ->
            actionWrapper.postRegisterHook(provider)
        }
}
复制代码最终发现是调用了  TaskContainer的 register(String var1, Class<T> var2, Action<? super T> var3);
所以最终还是要看Gradle API文档看下这个方法是干啥的

原来是创建一个新的任务,而任务名字和类型就是参数name,和type

所以需要回去看一下传入的name和type是什么
 public void createCheckManifestTask(@NonNull VariantScope scope) {
        taskFactory.register(getCheckManifestConfig(scope));
    }
    protected CheckManifest.CreationAction getCheckManifestConfig(@NonNull VariantScope scope) {
        return new CheckManifest.CreationAction(scope, false);
    }
复制代码继续看下new CheckManifest.CreationAction
 public static class CreationAction extends VariantTaskCreationAction<CheckManifest> {
        ...
        @NonNull
        @Override
        public String getName() {
            return getVariantScope().getTaskName("check", "Manifest");
        }
        @NonNull
        @Override
        public Class<CheckManifest> getType() {
            return CheckManifest.class;
        }
       ...
    }
复制代码最后发现这个Task的名字是checkXXXManifest,任务的类型是CheckManifest,所以CheckManifest就是task的实现类
public class CheckManifest extends AndroidVariantTask {
...
}
abstract class AndroidVariantTask : DefaultTask(), VariantAwareTask {
}
复制代码这样就找到了一个Task的实现类
Dex的编译过程源码分析
我们从这个方法开始分析Add a compile task
  @Override
    public void createTasksForVariantScope(@NonNull final VariantScope variantScope) {
        createAnchorTasks(variantScope);
        createCheckManifestTask(variantScope);
        ...
        // Add a compile task
        createCompileTask(variantScope);
        ...
    }
复制代码    protected void createCompileTask(@NonNull VariantScope variantScope) {
        TaskProvider<? extends JavaCompile> javacTask = createJavacTask(variantScope);
        addJavacClassesStream(variantScope);
        setJavaCompilerTask(javacTask, variantScope);
        createPostCompilationTasks(variantScope);
    }
复制代码首先创建了javac任务,任务名为compileXXXJavaWithJavac,实现类为AndroidJavaCompile,该Task的任务就是讲java源文件编译成class,接下来看一下createPostCompilationTasks方法
    public void createPostCompilationTasks(
            @NonNull final VariantScope variantScope) {
        
        AndroidConfig extension = variantScope.getGlobalScope().getExtension();
        // Merge Java Resources.
        //java资源合并
        createMergeJavaResTransform(variantScope);
        // ----- External Transforms -----
        // apply all the external transforms.
        //添加所有的transforms到transformManager
        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);
            List<Object> deps = customTransformsDependencies.get(i);
            transformManager.addTransform(
                    taskFactory,
                    variantScope,
                    transform,
                    null,
                    task -> {
                        if (!deps.isEmpty()) {
                            task.dependsOn(deps);
                        }
                    },
                    taskProvider -> {
                        // if the task is a no-op then we make assemble task depend on it.
                        if (transform.getScopes().isEmpty()) {
                            TaskFactoryUtils.dependsOn(
                                    variantScope.getTaskContainer().getAssembleTask(),
                                    taskProvider);
                        }
                    });
        }
        ...
        // ----- Minify next -----
        //如果启用minifyEnabled=true,进行代码缩减,就是进行混淆
        CodeShrinker shrinker = maybeCreateJavaCodeShrinkerTransform(variantScope);
        if (shrinker == CodeShrinker.R8) {
            //如果是R8执行资源缩减
            maybeCreateResourcesShrinkerTransform(variantScope);
            maybeCreateDexSplitterTransform(variantScope);
            // TODO: create JavaResSplitterTransform and call it here (http://b/77546738)
            return;
        }
        // ----- 10x support
        //InstantRun 支持
        TaskProvider<PreColdSwapTask> preColdSwapTask = null;
        if (variantScope.getInstantRunBuildContext().isInInstantRunMode()) {
            TaskProvider<? extends Task> allActionsAnchorTask =
                    createInstantRunAllActionsTasks(variantScope);
            assert variantScope.getInstantRunTaskManager() != null;
            preColdSwapTask =
                    variantScope.getInstantRunTaskManager().createPreColdswapTask(projectOptions);
            TaskFactoryUtils.dependsOn(preColdSwapTask, allActionsAnchorTask);
        }
        // ----- Multi-Dex support
        //Multi-Dex 支持
        DexingType dexingType = variantScope.getDexingType();
        // Upgrade from legacy multi-dex to native multi-dex if possible when using with a device
        if (dexingType == DexingType.LEGACY_MULTIDEX) {
            if (variantScope.getVariantConfiguration().isMultiDexEnabled()
                    && variantScope
                                    .getVariantConfiguration()
                                    .getMinSdkVersionWithTargetDeviceApi()
                                    .getFeatureLevel()
                            >= 21) {
                dexingType = DexingType.NATIVE_MULTIDEX;
            }
        }
        ...
        //创建Dex task
        createDexTasks(variantScope, dexingType);
        ...
    }
复制代码这个主要做了一下几个工作
- java资源合并
- 添加所有的transforms到transformManager
- 如果启用minifyEnabled=true,进行代码缩减,就是进行混淆
- 如果是R8执行资源缩减
- InstantRun 支持
- Multi-Dex 支持
- 创建Dex task
这里创建的Dex Task 其实就是TransfromTask类型,下面了解一下TransfromTask
/** A task running a transform. */
@CacheableTask
public class TransformTask extends StreamBasedTask implements Context {
    @TaskAction
    void transform(final IncrementalTaskInputs incrementalTaskInputs)
            throws IOException, TransformException, InterruptedException {
        ....
        recorder.record(
                ExecutionType.TASK_TRANSFORM,
                executionInfo,
                getProject().getPath(),
                getVariantName(),
                new Recorder.Block<Void>() {
                    @Override
                    public Void call() throws Exception {
                        transform.transform(
                                new TransformInvocationBuilder(TransformTask.this)
                                        .addInputs(consumedInputs.getValue())
                                        .addReferencedInputs(referencedInputs.getValue())
                                        .addSecondaryInputs(changedSecondaryInputs.getValue())
                                        .addOutputProvider(
                                                outputStream != null
                                                        ? outputStream.asOutput(
                                                                isIncremental.getValue())
                                                        : null)
                                        .setIncrementalMode(isIncremental.getValue())
                                        .build());
                        if (outputStream != null) {
                            outputStream.save();
                        }
                        return null;
                    }
                });
    }
    ...
      
}
复制代码最终调用了transform的transform,也就是调用了DexArchiveBuilderTransform的transform
public class DexArchiveBuilderTransform extends Transform {
    ...
}
复制代码下面的需要了解一些Transform知识,可以看我之前的文章Gradle学习系列(五):Gradle Transform
读到这里我恍然大悟,原来我们自定义的Transform,添加到了extension中,然后在打包阶段编译java->class之后,class->dex之前,遍历extension中的Transform(包括我们自定义的)然后添加到TransformManager 注册为 TransformTask,当执行Task时候,在调用Transform的transform方法,这样就达到了在dex之前修改字节码的目的
下面继续看DexArchiveBuilderTransform的transform方法
  @Override
    public void transform(@NonNull TransformInvocation transformInvocation)
            throws TransformException, IOException, InterruptedException {
    
            //这里是遍历目录下的class文件
            for (TransformInput input : transformInvocation.getInputs()) {
                for (DirectoryInput dirInput : input.getDirectoryInputs()) {
                    logger.verbose("Dir input %s", dirInput.getFile().toString());
                    convertToDexArchive(
                            transformInvocation.getContext(),
                            dirInput,
                            outputProvider,
                            isIncremental,
                            bootclasspathServiceKey,
                            classpathServiceKey,
                            additionalPaths);
                }
                //这里是遍历jar中的class文件
                for (JarInput jarInput : input.getJarInputs()) {
                    logger.verbose("Jar input %s", jarInput.getFile().toString());
                    D8DesugaringCacheInfo cacheInfo =
                            getD8DesugaringCacheInfo(
                                    desugarIncrementalTransformHelper,
                                    bootclasspath,
                                    classpath,
                                    jarInput);
                    List<File> dexArchives =
                            processJarInput(
                                    transformInvocation.getContext(),
                                    isIncremental,
                                    jarInput,
                                    outputProvider,
                                    bootclasspathServiceKey,
                                    classpathServiceKey,
                                    additionalPaths,
                                    cacheInfo);
                    if (cacheInfo != D8DesugaringCacheInfo.DONT_CACHE && !dexArchives.isEmpty()) {
                        cacheableItems.add(
                                new DexArchiveBuilderCacheHandler.CacheableItem(
                                        jarInput,
                                        dexArchives,
                                        cacheInfo.orderedD8DesugaringDependencies));
                    }
                }
            }
    }
复制代码我们继续跟一下 convertToDexArchive方法,从方法名字就可以看出是转换为dex文件
    private List<File> convertToDexArchive(
            @NonNull Context context,
            @NonNull QualifiedContent input,
            @NonNull TransformOutputProvider outputProvider,
            boolean isIncremental,
            @NonNull ClasspathServiceKey bootClasspath,
            @NonNull ClasspathServiceKey classpath,
            @NonNull Set<File> additionalPaths) {
            ...
                executor.execute(
                        ...
                            try (Closeable ignored = output = outputHandler.createOutput()) {
                                launchProcessing(
                                        parameters,
                                        output.getStandardOutput(),
                                        output.getErrorOutput(),
                                        messageReceiver);
                            } 
            }
        }
        return dexArchives.build();
    }
复制代码最后调用了launchProcessing方法,继续跟进源码
  private static void launchProcessing(
            @NonNull DexConversionParameters dexConversionParameters,
            @NonNull OutputStream outStream,
            @NonNull OutputStream errStream,
            @NonNull MessageReceiver receiver)
            throws IOException, URISyntaxException {
        DexArchiveBuilder dexArchiveBuilder =
                getDexArchiveBuilder(
                        dexConversionParameters.minSdkVersion,
                        dexConversionParameters.dexAdditionalParameters,
                        dexConversionParameters.inBufferSize,
                        dexConversionParameters.outBufferSize,
                        dexConversionParameters.bootClasspath,
                        dexConversionParameters.classpath,
                        dexConversionParameters.dexer,
                        dexConversionParameters.isDebuggable,
                        VariantScope.Java8LangSupport.D8
                                == dexConversionParameters.java8LangSupportType,
                        outStream,
                        errStream,
                        receiver);
        ...
        try (ClassFileInput input = ClassFileInputs.fromPath(inputPath);
                Stream<ClassFileEntry> entries = input.entries(bucketFilter)) {
            dexArchiveBuilder.convert(
                    entries,
                    Paths.get(new URI(dexConversionParameters.output)),
                    dexConversionParameters.isDirectoryBased());
        } catch (DexArchiveBuilderException ex) {
            throw new DexArchiveBuilderException("Failed to process " + inputPath.toString(), ex);
        }
    }
复制代码最终调用dexArchiveBuilder.convert 而 DexArchiveBuilder有俩个实现类 D8DexArchiveBuilder 和 DxDexArchiveBuilder在这里最中转换为dex文件
dex编译总结
- 首先创建了javac任务,该Task的任务就是讲java源文件编译成class
- java资源合并
- 添加所有的transforms到transformManager
- 如果启用minifyEnabled=true,进行代码缩减,就是进行混淆
- 如果是R8执行资源缩减
- InstantRun 支持
- Multi-Dex 支持
- 创建Dex task
- 最终D8DexArchiveBuilder和DxDexArchiveBuilder在这里最中转换为dex文件
总结
Android Gradle Plugin 主要做了三件事
- 
配置项目,主要做了以下工作 - 创建SdkHandler,为Gradle插件处理所有的事情的sdk。每个项目大约有一个实例
- 创建AndroidBuilder,这是主构建器类。它得到了所有用于处理构建的数据(例如{@linkDefaultProductFlavor}、{@link DefaultBuildType}和依赖项)
- 创建DataBindingBuilder
- 强制使用不低于当前支持插件的最小版本
- 应用java插件
- 创建构建缓存,如果启用,构建缓存目录将设置为用户定义的目录,如果用户定义的目录没有提供,则为默认目录
- 创建全局作用域,主要是为Android plugin 保存数据
- 找到assemble Task 添加描述
- 监听构建完成回调,做一些清尾工作
 
- 
配置扩展 - 
配置不定项扩展BuildType,ProductFlavor,SigningConfig,BaseVariantOutput buildTypes { release {} debug {} vip {} aaa {} } flavorDimensions "xiaomi", "huawei" productFlavors { JD { dimension("xiaomi") } TAO { dimension("xiaomi") } PIN { dimension("huawei") } } 复制代码所以我们才可以这样自定义每一项的名字,可以配置多项 
- 
创建android 扩展,也就是我们最常用的 android { compileSdkVersion 29 ... } 复制代码
- 
创建TaskManager,任务管理类 
- 
创建VariantManager,变体管理类 
- 
按顺序依次创建 signingConfig debug、buildType debug、buildType releas类型的 DSL。 
 
- 
- 
创建任务 这个最终会调用 ApplicationTaskManager 的 createTasksForVariantScope,在这个方法内部创建一系列适用于应用构建的Task,这里只保留了注释@Override public void createTasksForVariantScope(@NonNull final VariantScope variantScope) { createAnchorTasks(variantScope); createCheckManifestTask(variantScope); handleMicroApp(variantScope); // Create all current streams (dependencies mostly at this point) createDependencyStreams(variantScope); // Add a task to publish the applicationId. createApplicationIdWriterTask(variantScope); // Add a task to process the manifest(s) // Add a task to create the res values // Add a task to compile renderscript files. // Add a task to merge the resource folders // Add tasks to compile shader // Add a task to merge the asset folders // Add a task to create the BuildConfig class // Add a task to process the Android Resources and generate source files // Add a task to process the java resources // Add external native build tasks // Add a task to merge the jni libs folders // Add feature related tasks if necessary // Add data binding tasks if enabled // Add a compile task } 复制代码
- 
然后分析了如何找到每个Task的实现类 
- 
最后具体分析了Dex Task的工作流程 




















![[02/27][官改] Simplicity@MIX2 ROM更新-一一网](https://www.proyy.com/wp-content/uploads/2020/02/3168457341.jpg)



![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)
