Android gradle打包涉及task源码解析(四)

文章序号

此篇文章将分析如下11个task。

:app:splitsDiscoveryTaskDebug UP-TO-DATE
:app:processDebugResources
:app:generateDebugSources
:app:javaPreCompileDebug
:app:compileDebugJavaWithJavac
:app:compileDebugNdk NO-SOURCE
:app:compileDebugSources
:app:mergeDebugShaders
:app:compileDebugShaders
:app:generateDebugAssets
:app:mergeDebugAssets

splitsDiscoveryTaskDebug

执行命令:./gradlew splitsDiscoveryTaskDebug

  • inputs&outputs
output file:/Users/zhengchao/Documents/AndroidSpace/OpenSpace/TasksPro/app/build/intermediates/splits-support/debug/split-list.gson

split-list.json 文件内容如下:

[{
    "splitType": "DENSITY",
    "values": ["mdpi", "hdpi", "xhdpi"]
}, {
    "splitType": "LANGUAGE",
    "values": []
}, {
    "splitType": "ABI",
    "values": []
}, {
    "splitType": "ResConfigs",
    "values": []
}]

通过输出json文件,基本可以才到splitsDiscoveryTaskDebug任务就是把项目有关的split都再次聚合生成了一个json文件。

  • 源码

https://android.googlesource.com/platform/tools/base/+/gradle_3.0.0/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/SplitsDiscovery.java

  • 主要代码逻辑

SplitsDiscovery.java 中的taskAction()方法。

    void taskAction() throws IOException {
        Set<File> mergedResourcesFolderFiles =
                mergedResourcesFolders != null ? mergedResourcesFolders.getFiles() : null;
        Collection<String> resConfigs = resourceConfigs;
        if (resConfigAuto) {
            resConfigs = discoverListOfResourceConfigsNotDensities();
        }
        SplitList.save(
                getPersistedList(),
                getFilters(mergedResourcesFolderFiles, DiscoverableFilterType.DENSITY),
                getFilters(mergedResourcesFolderFiles, DiscoverableFilterType.LANGUAGE),
                // no need to pass the source folders, we don't support Auto for ABI splits so far.
                getFilters(ImmutableList.of(), DiscoverableFilterType.ABI),
                resConfigs);
    }

直接看最后一句代码就行了,实现对DENSITY、LANGUAGE、ABI和resConfig配置的存储,即生成split-list.json文件。

processDebugResources

执行命令:./gradlew processDebugResources

  • inputs&outputs
input file:/Users/zhengchao/Documents/AndroidSpace/OpenSpace/TasksPro/app/build/intermediates/res/merged/debug
input file:/Users/zhengchao/Documents/AndroidSpace/OpenSpace/TasksPro/app/build/intermediates/manifests/full/debug
input file:/Users/zhengchao/Documents/AndroidSpace/OpenSpace/TasksPro/app/build/intermediates/splits-support/debug/split-list.gson
input file:/Users/zhengchao/.gradle/caches/transforms-1/files-1.1/a7cc521b4567369eba0ddb355f44a660/21d0ae01f3b4e29e6c802c00ffced930/package-aware-r.txt
input file:/Users/zhengchao/.gradle/caches/transforms-1/files-1.1/604f3f8b356720eda7bfab425c06a06e/371c636e802b54ae62f24ca3b8983aa4/package-aware-r.txt
input file:/Users/zhengchao/.gradle/caches/transforms-1/files-1.1/91acff2d03a16c67323da40e829163bd/fa97ea8e56458564023fc312949aac2e/package-aware-r.txt
input file:/Users/zhengchao/.gradle/caches/transforms-1/files-1.1/a4e729d586b413dec60d9faca70e7901/6338b6741f916337f8e90073f389bd2a/package-aware-r.txt
input file:/Users/zhengchao/.gradle/caches/transforms-1/files-1.1/0f8bcb3b30938c09cb5d45a38670a61a/327ff0b63de18940597e89288c74ad4b/package-aware-r.txt
input file:/Users/zhengchao/.gradle/caches/transforms-1/files-1.1/500188dffd88c5be8587eb6372bbf06d/44df2544155d6c7f2d9d860dc81b2987/package-aware-r.txt
input file:/Users/zhengchao/.gradle/caches/transforms-1/files-1.1/7fd9e164f67367b6857914be5e5a3aa7/7bc85529df0e5dfea9848a731eb5e623/package-aware-r.txt
input file:/Users/zhengchao/.gradle/caches/transforms-1/files-1.1/a5a5c709ac0291e9c3bdb096074909c7/953f5d6737013091f79cdf83a4e500c1/package-aware-r.txt
input file:/Users/zhengchao/.gradle/caches/transforms-1/files-1.1/6b0cfb67d4e7be9680a05836fc807a20/e2734ac50593541599802c3547ef2197/package-aware-r.txt
input file:/Users/zhengchao/.gradle/caches/transforms-1/files-1.1/9806df9e60c4aacc7f9f357a91ad2e92/f56c8e1c2d1e598093ccd977e250c742/package-aware-r.txt
input file:/Users/zhengchao/.gradle/caches/transforms-1/files-1.1/8ce7d74e9940aacec93d142f00568824/b6e216a8726556e88e69ce4b671bce42/package-aware-r.txt
---------------------------------------------------
output file:/Users/zhengchao/Documents/AndroidSpace/OpenSpace/TasksPro/app/build/intermediates/incremental/processDebugResources
output file:/Users/zhengchao/Documents/AndroidSpace/OpenSpace/TasksPro/app/build/intermediates/res/debug
output file:/Users/zhengchao/Documents/AndroidSpace/OpenSpace/TasksPro/app/build/generated/source/r/debug
output file:/Users/zhengchao/Documents/AndroidSpace/OpenSpace/TasksPro/app/build/intermediates/res/symbol-table-with-package/debug/package-aware-r.txt
output file:/Users/zhengchao/Documents/AndroidSpace/OpenSpace/TasksPro/app/build/intermediates/symbols/debug/R.txt

首先看下输入目录类型:

1、mergeDebugResources 任务的输出目录,intermediates/res/merged/debug该文件夹下是经过aapt处理过的flat文件;

2、processDebugManifest 任务的输出目录,intermediates/manifests/full/debug该文件夹下是生成的manifest.xml文件;

3、splitsDiscoveryTaskDebug任务输出的目录;

4、各个依赖包的cache目录中的package-aware-r.txt文件,该文件里面的内容是相应包的资源的映射,如下:

android.support.v7.appcompat
int anim abc_fade_in 0x7f010001
int anim abc_fade_out 0x7f010002
int anim abc_grow_fade_in_from_bottom 0x7f010003
int anim abc_popup_enter 0x7f010004

第一行是包名,后面是资源的映射关系。

再来看下输出目录:

1、/intermediates/incremental/processDebugResources这个先忽略,后面再说;

2、/intermediates/res/debug该目录下主要是resources.ap_文件,该文件实际就是资源通过aapt后生成的资源压缩文件(解压后会发现里面就是:AndroidManifest.xml、res文件,以及resoures.arsc);

3、/generated/source/r/debug该目录也就是R.java文件。

4、symbol-table-with-package/debug/package-aware-r.txt生成项目的R文件的映射关系;

5、intermediates/symbols/debug/R.txt生成R文件的txt文件。

  • 源码

https://android.googlesource.com/platform/tools/base/+/gradle_3.0.0/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/ProcessAndroidResources.java

  • 主要代码逻辑

ProcessAndroidResources.java 中的doFullTaskAction()方法。

@Override
    protected void doFullTaskAction() throws IOException, ExecutionException {
        ...
        try (Aapt aapt = bypassAapt ? null : makeAapt()) {

            // do a first pass at the list so we generate the code synchronously since it's required
            // by the full splits asynchronous processing below.
            List<ApkData> apkDataList = new ArrayList<>(splitsToGenerate);
            for (ApkData apkData : splitsToGenerate) {
                if (apkData.requiresAapt()) {
                    boolean codeGen =
                            (apkData.getType() == OutputFile.OutputType.MAIN
                                    || apkData.getFilter(OutputFile.FilterType.DENSITY) == null);
                    if (codeGen) {
                        apkDataList.remove(apkData);
                        // 调用invokeAaptForSplit();
                        invokeAaptForSplit(
                                manifestsOutputs,
                                libraryInfoList,
                                packageIdFileSet,
                                splitList,
                                featureResourcePackages,
                                apkData,
                                codeGen,
                                aapt);
                        break;
                    }
                }
            }

            // now all remaining splits will be generated asynchronously.
            for (ApkData apkData : apkDataList) {
                if (apkData.requiresAapt()) {
                    executor.execute(
                            () -> {
                                invokeAaptForSplit(
                                        manifestsOutputs,
                                        libraryInfoList,
                                        packageIdFileSet,
                                        splitList,
                                        featureResourcePackages,
                                        apkData,
                                        false,
                                        aapt);
                                return null;
                            });
                }
        ...
        // and save the metadata file.
        outputScope.save(
                ImmutableList.of(
                        VariantScope.TaskOutputType.DENSITY_OR_LANGUAGE_SPLIT_PROCESSED_RES,
                        VariantScope.TaskOutputType.PROCESSED_RES),
                resPackageOutputFolder);
    }

核心代码调用invokeAaptForSplit()方法。

void invokeAaptForSplit(
            Collection<BuildOutput> manifestsOutputs,
            @NonNull Set<File> dependencySymbolTableFiles,
            @Nullable Set<File> packageIdFileSet,
            @NonNull SplitList splitList,
            @NonNull Set<File> featureResourcePackages,
            ApkData apkData,
            boolean generateCode,
            @Nullable Aapt aapt)
            throws IOException {
        // *.ap_ 文件
        File resOutBaseNameFile =
                new File(
                        resPackageOutputFolder,
                        FN_RES_BASE
                                + RES_QUALIFIER_SEP
                                + apkData.getFullName()
                                + SdkConstants.DOT_RES);
        ...
        // manifest file
        File manifestFile = manifestOutput.getOutputFile();

        ...
        // 生产相应的文件
        getBuilder().processResources(aapt, config);

    }

processDebugResources这个任务的代码有些长,但是主要逻辑很清晰,就是根据我们前面分析的输入文件,生成我们的resoure(*.ap_)文件,已经相应的R文件。

generateDebugSources

忽略

javaPreCompileDebug

  • 准备

引入'butterknife':

命令行输入:./gradlew javaPreCompileDebug

  • inputs&outputs
input file:/Users/chao.zheng/.gradle/caches/modules-2/files-2.1/com.jakewharton/butterknife-compiler/9.0.0-rc2/dcb492fc3d86c39cdc8d00ccacc259bac7a00634/butterknife-compiler-9.0.0-rc2.jar
input file:/Users/chao.zheng/.gradle/caches/modules-2/files-2.1/com.squareup/javapoet/1.10.0/712c178d35185d8261295913c9f2a7d6867a6007/javapoet-1.10.0.jar
input file:/Users/chao.zheng/.gradle/caches/modules-2/files-2.1/com.jakewharton/butterknife-annotations/9.0.0-rc2/b2542071aa4b048d2ac0bf6b6e430be5a1755c3f/butterknife-annotations-9.0.0-rc2.jar
input file:/Users/chao.zheng/.gradle/caches/modules-2/files-2.1/com.google.auto/auto-common/0.10/c8f153ebe04a17183480ab4016098055fb474364/auto-common-0.10.jar
input file:/Users/chao.zheng/.gradle/caches/modules-2/files-2.1/com.google.guava/guava/24.0-jre/41ac1e74d6b4e1ea1f027139cffeb536c732a81/guava-24.0-jre.jar
input file:/Users/chao.zheng/.gradle/caches/modules-2/files-2.1/com.android.support/support-annotations/28.0.0/ed73f5337a002d1fd24339d5fb08c2c9d9ca60d8/support-annotations-28.0.0.jar
input file:/Users/chao.zheng/.gradle/caches/modules-2/files-2.1/com.google.code.findbugs/jsr305/1.3.9/40719ea6961c0cb6afaeb6a921eaa1f6afd4cfdf/jsr305-1.3.9.jar
input file:/Users/chao.zheng/.gradle/caches/modules-2/files-2.1/org.checkerframework/checker-compat-qual/2.0.0/fc89b03860d11d6213d0154a62bcd1c2f69b9efa/checker-compat-qual-2.0.0.jar
input file:/Users/chao.zheng/.gradle/caches/modules-2/files-2.1/com.google.errorprone/error_prone_annotations/2.1.3/39b109f2cd352b2d71b52a3b5a1a9850e1dc304b/error_prone_annotations-2.1.3.jar
input file:/Users/chao.zheng/.gradle/caches/modules-2/files-2.1/com.google.j2objc/j2objc-annotations/1.1/976d8d30bebc251db406f2bdb3eb01962b5685b3/j2objc-annotations-1.1.jar
input file:/Users/chao.zheng/.gradle/caches/modules-2/files-2.1/org.codehaus.mojo/animal-sniffer-annotations/1.14/775b7e22fb10026eed3f86e8dc556dfafe35f2d5/animal-sniffer-annotations-1.14.jar
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/appcompat-v7-26.1.0.aar/6b443e96f1af9aa241aaa70576c67a57/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/constraint-layout-1.1.3.aar/f44da5c361a1f52801511229596f72e7/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/butterknife-9.0.0-rc2.aar/8621d7bdb16992184dcd908b05a88089/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/animated-vector-drawable-26.1.0.aar/9c804d63d6f065a8f9945f9ad94fee0e/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/support-vector-drawable-26.1.0.aar/4e56cc34abf77378e2b8d16ee237c82d/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/support-v4-26.1.0.aar/3bf8586900bd31e222ef8b68bfd6e744/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/support-media-compat-26.1.0.aar/267524a16ca7128dd9cef3c19f394439/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/support-fragment-26.1.0.aar/77cf518e9868987a283f04cec221fefa/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/support-core-utils-26.1.0.aar/8634ab1afa6a5a1a947a7bd163aba14f/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/support-core-ui-26.1.0.aar/8902e2a864b44d47c26fbc80fdafe175/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/butterknife-runtime-9.0.0-rc2.aar/52a0e29c9a97888250a7dcafb4b772d2/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/support-compat-28.0.0.aar/0f01dd979a4412cc88bd76adabeaa35f/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/versionedparcelable-28.0.0.aar/c52cdc9f13c25171d1f8c643b784dff9/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/modules-2/files-2.1/com.android.support/collections/28.0.0/c1bcdade4d3cc2836130424a3f3e4182c666a745/collections-28.0.0.jar
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/runtime-1.1.1.aar/37b34991d517509bf0bc71acfb777556/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/modules-2/files-2.1/android.arch.lifecycle/common/1.1.1/207a6efae6a3555e326de41f76bdadd9a239cbce/common-1.1.1.jar
input file:/Users/chao.zheng/.gradle/caches/modules-2/files-2.1/android.arch.core/common/1.1.1/e55b70d1f5620db124b3e85a7f4bdc7bd48d9f95/common-1.1.1.jar
input file:/Users/chao.zheng/.gradle/caches/modules-2/files-2.1/com.android.support.constraint/constraint-layout-solver/1.1.3/bde0667d7414c16ed62d3cfe993cff7f9d732373/constraint-layout-solver-1.1.3.jar
---------------------------------------------------
output file:/Users/chao.zheng/sunday/OpenSpace/TasksPro/app/build/intermediates/javaPrecompile/debug/annotationProcessors.json

查看input file,会发现所有的输入均为项目直接或者间接引用到的库的jar包。

output file 是一个annotationProcessors.json文件。文件如下:

["butterknife-compiler.jar (com.jakewharton:butterknife-compiler:9.0.0-rc2)"]

通过输入输出我们大致的可以分析出来'javaPreCompileDebug'任务就是生成使用了AnnotationProcessors依赖的json映射关系。

  • 源码

https://android.googlesource.com/platform/tools/base/+/gradle_3.0.0/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/JavaPreCompileTask.java

  • 主要代码逻辑
    @TaskAction
    public void preCompile() throws IOException {
        ...
        
        // Get all the annotation processors for metrics collection.
        Set<String> classNames = Sets.newHashSet();
        // 1、通过includeCompileClasspath 配置的annotation processors;
        // Add the annotation processors on classpath only when includeCompileClasspath is true.
        if (Boolean.TRUE.equals(annotationProcessorOptions.getIncludeCompileClasspath())) {
            if (compileProcessors == null) {
                compileProcessors = collectAnnotationProcessors(compileClasspaths);
            }
            classNames.addAll(convertArtifactsToNames(compileProcessors));
        }
        // 2、通过configuration 配置的 annotation processor。
        // Add all annotation processors on the annotation processor configuration.
        classNames.addAll(
                convertArtifactsToNames(
                        collectAnnotationProcessors(annotationProcessorConfiguration)));

        // 3、通过annotationProcessorOptions 配置的annotation processor。
        // Add the explicitly declared processors.
        // For metrics purposes, we don't care how they include the processor in their build.
        classNames.addAll(annotationProcessorOptions.getClassNames());

        // 4、使用dataBinding框架。
        // Add a generic reference to data binding, if present.
        if (dataBindingEnabled) {
            classNames.add(DATA_BINDING_SPEC);
        }

        FileUtils.deleteIfExists(processorListFile);
        Gson gson = new GsonBuilder().create();
        try (FileWriter writer = new FileWriter(processorListFile)) {
            gson.toJson(classNames, writer);
        }
    }

通过代码可以发现,javaPreCompileDebug任务就是将4️类型的annotationProcessor添加到 className中,最后将起保存为json文件。

compileDebugJavaWithJavac

执行命令:./gradlew compileDebugJavaWithJavac

  • inputs&outputs
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/appcompat-v7-26.1.0.aar/6b443e96f1af9aa241aaa70576c67a57/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/constraint-layout-1.1.3.aar/f44da5c361a1f52801511229596f72e7/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/butterknife-8.5.1.aar/9d5de52440cb778daab09db33955642f/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/animated-vector-drawable-26.1.0.aar/9c804d63d6f065a8f9945f9ad94fee0e/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/support-vector-drawable-26.1.0.aar/4e56cc34abf77378e2b8d16ee237c82d/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/modules-2/files-2.1/com.jakewharton/butterknife-annotations/8.5.1/bb67dad90bab7cd77a8f7f1b8442b47e3a2326bc/butterknife-annotations-8.5.1.jar
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/support-v4-26.1.0.aar/3bf8586900bd31e222ef8b68bfd6e744/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/support-media-compat-26.1.0.aar/267524a16ca7128dd9cef3c19f394439/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/support-fragment-26.1.0.aar/77cf518e9868987a283f04cec221fefa/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/support-core-utils-26.1.0.aar/8634ab1afa6a5a1a947a7bd163aba14f/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/support-core-ui-26.1.0.aar/8902e2a864b44d47c26fbc80fdafe175/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/support-compat-26.1.0.aar/3e4c87483eacfb4c962d7380a59a114d/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/modules-2/files-2.1/com.android.support/support-annotations/26.1.0/814258103cf26a15fcc26ecce35f5b7d24b73f8/support-annotations-26.1.0.jar
input file:/Users/chao.zheng/.gradle/caches/modules-2/files-2.1/com.android.support.constraint/constraint-layout-solver/1.1.3/bde0667d7414c16ed62d3cfe993cff7f9d732373/constraint-layout-solver-1.1.3.jar
input file:/Users/chao.zheng/.gradle/caches/transforms-1/files-1.1/runtime-1.0.0.aar/ed085e7b9476f7a9fef4ffbb323166ba/jars/classes.jar
input file:/Users/chao.zheng/.gradle/caches/modules-2/files-2.1/android.arch.lifecycle/common/1.0.0/e414a4cb28434e25c4f6aa71426eb20cf4874ae9/common-1.0.0.jar
input file:/Users/chao.zheng/.gradle/caches/modules-2/files-2.1/android.arch.core/common/1.0.0/a2d487452376193fc8c103dd2b9bd5f2b1b44563/common-1.0.0.jar
input file:/Users/chao.zheng/sunday/OpenSpace/TasksPro/app/build/intermediates/javaPrecompile/debug/annotationProcessors.json
input file:/Users/chao.zheng/sunday/OpenSpace/TasksPro/app/src/main/java/org/test/task/MainActivity.java
input file:/Users/chao.zheng/sunday/OpenSpace/TasksPro/app/src/main/java/org/test/task/Test.java
input file:/Users/chao.zheng/sunday/OpenSpace/TasksPro/app/build/generated/source/r/debug/org/test/task11/R2.java
input file:/Users/chao.zheng/sunday/OpenSpace/TasksPro/app/build/generated/source/r/debug/org/test/task11/R.java
input file:/Users/chao.zheng/sunday/OpenSpace/TasksPro/app/build/generated/source/r/debug/android/support/coreutils/R.java
input file:/Users/chao.zheng/sunday/OpenSpace/TasksPro/app/build/generated/source/r/debug/android/support/v7/appcompat/R.java
input file:/Users/chao.zheng/sunday/OpenSpace/TasksPro/app/build/generated/source/r/debug/android/support/compat/R.java
input file:/Users/chao.zheng/sunday/OpenSpace/TasksPro/app/build/generated/source/r/debug/android/support/coreui/R.java
input file:/Users/chao.zheng/sunday/OpenSpace/TasksPro/app/build/generated/source/r/debug/android/support/v4/R.java
input file:/Users/chao.zheng/sunday/OpenSpace/TasksPro/app/build/generated/source/r/debug/android/support/fragment/R.java
input file:/Users/chao.zheng/sunday/OpenSpace/TasksPro/app/build/generated/source/r/debug/android/support/graphics/drawable/R.java
input file:/Users/chao.zheng/sunday/OpenSpace/TasksPro/app/build/generated/source/r/debug/android/support/graphics/drawable/animated/R.java
input file:/Users/chao.zheng/sunday/OpenSpace/TasksPro/app/build/generated/source/r/debug/android/support/mediacompat/R.java
input file:/Users/chao.zheng/sunday/OpenSpace/TasksPro/app/build/generated/source/r/debug/android/support/constraint/R.java
input file:/Users/chao.zheng/sunday/OpenSpace/TasksPro/app/build/generated/source/r/debug/android/arch/lifecycle/R.java
input file:/Users/chao.zheng/sunday/OpenSpace/TasksPro/app/build/generated/source/r/debug/butterknife/R.java
input file:/Users/chao.zheng/sunday/OpenSpace/TasksPro/app/build/generated/source/buildConfig/debug/org/test/task11/BuildConfig.java
input file:/Users/chao.zheng/sunday/OpenSpace/TasksPro/app/build/generated/source/aidl/debug/org/test/task/IMyAidlInterface.java
---------------------------------------------------
output file:/Users/chao.zheng/sunday/OpenSpace/TasksPro/app/build/generated/source/apt/debug
output file:/Users/chao.zheng/sunday/OpenSpace/TasksPro/app/build/intermediates/classes/debug

输入文件类型:

1、依赖工程的jar文件;

2、javaPreCompileDebug 任务的输出json文件(javaPrecompile/debug/annotationProcessors.json);

3、项目的java文件(java/org/test/task/MainActivity.java);

4、项目生成的R文件(source/r/debug/butterknife/R.java)、BuildConfig文件(buildConfig/debug/org/test/task11/BuildConfig.java)、Aidl文件(aidl/debug/org/test/task/IMyAidlInterface.java);

输出文件类型:

1、annotationProcessor 生成的java文件(generated/source/apt/debug)

2、生成的classes文件(intermediates/classes/debug)

通过这个输入和输出基本能分析出来compileDebugJavaWithJavac任务是做两件事:1、通过annotation processor生成相应的java文件;2、将项目的所有java文件(包括R、BuildConfig、Aidl等)通过javac编译成class文件。

  • 源码

https://android.googlesource.com/platform/tools/base/+/gradle_3.0.0/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/factory/AndroidJavaCompile.java

compile的核心逻辑实际上不在AndroidJavaCompile这个类里面,该类继承了JavaCompile类,核心编译逻辑实际在com.sun.tools.javac.main.Main.java类里面的compile()方法。通过包名也能看出该类就是javac里面的核心类,具体代码逻辑不在分析,有兴趣的自行查看。

compileDebugNdk

mergeDebugShaders

compileDebugShaders

generateDebugAssets

以上几个task跟ndk开发相关,在此不再分析。

mergeDebugAssets

执行命令:./gradlew mergeDebugAssets

  • inputs&outputs
input file:/Users/zhengchao/Documents/AndroidSpace/OpenSpace/TasksPro/app/build/generated/assets/shaders/debug
input file:/Users/zhengchao/Documents/AndroidSpace/OpenSpace/TasksPro/app/src/main/assets
input file:/Users/zhengchao/Documents/AndroidSpace/OpenSpace/TasksPro/app/src/debug/assets
---------------------------------------------------
output file:/Users/zhengchao/Documents/AndroidSpace/OpenSpace/TasksPro/app/build/intermediates/incremental/mergeDebugAssets
output file:/Users/zhengchao/Documents/AndroidSpace/OpenSpace/TasksPro/app/build/intermediates/assets/debug

根据输入输出大致可以分析出将生成的assets和项目的assets里面的文件合并到intermediates/assets/debug目录下。

  • 源码

https://android.googlesource.com/platform/tools/base/+/gradle_3.0.0/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/MergeSourceSetFolders.java

  • 主要代码逻辑

MergeSourceSetFolders中的doFullTaskAction()方法。

protected void doFullTaskAction() throws IOException {
        // this is full run, clean the previous output
        File destinationDir = getOutputDir();
        FileUtils.cleanOutputDir(destinationDir);
        
        // 1、assets 集合
        List<AssetSet> assetSets = computeAssetSetList();

        // create a new merger and populate it with the sets.
        AssetMerger merger = new AssetMerger();

        try {
            // 2、遍历assets集合,添加AssetMerger中
            for (AssetSet assetSet : assetSets) {
                // set needs to be loaded.
                assetSet.loadFromFiles(getILogger());
                merger.addDataSet(assetSet);
            }

            // get the merged set and write it down.
            MergedAssetWriter writer = new MergedAssetWriter(destinationDir, workerExecutor);

            merger.mergeData(writer, false /*doCleanUp*/);
            // 3、写到指定目录
            // No exception? Write the known state.
            merger.writeBlobTo(getIncrementalFolder(), writer, false);
        } catch (MergingException e) {
            getLogger().error("Could not merge source set folders: ", e);
            merger.cleanBlob(getIncrementalFolder());
            throw new ResourceException(e.getMessage(), e);
        }
    }

通过代码注释说明,可以看出mergeDebugAssets和我们前面分析的是一致的。

推荐阅读更多精彩内容