Android 探索之 Task 分析(七)

本文将会分析如下几个task

generateReleaseAssets
mergeReleaseAssets
extractTryWithResourcesSupportJarRelease
transformClassesWithStackFramesFixerForRelease
transformClassesWithDesugarForRelease
processReleaseJavaRes

25.generateReleaseAssets

锚点task,参见TaskManager.createAnchorTasks

源码分析

anchor

输入输出

-----task begin-------->
project:     project ':app_driver' 
name:        generateReleaseAssets 
group:       null 
description: null
conv:        [:]
inputs:
outputs:
<------task end -------

26.mergeReleaseAssets

源码分析

//com.android.build.gradle.tasks.MergeSourceSetFolders
 @Override
    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);
        }
    }

输入输出

-----task begin-------->
project:     project ':app_driver' 
name:        mergeReleaseAssets 
group:       null 
description: null
conv:        [:]
inputs:
 /Users/dongkai/Code/XiWeiLogistics/ymm_app_driver_main_module/build/intermediates/packagedAssets/release
 /Users/dongkai/Code/XiWeiLogistics/biz_common/build/intermediates/packagedAssets/release
 /Users/dongkai/.gradle/caches/transforms-1/files-1.1/ymm_account-1.16.0.aar/9b755ac72f1b744af95a603c6aba7e2f/assets
 /Users/dongkai/.gradle/caches/transforms-1/files-1.1/web-sdk-1.9.0.aar/b642021cdc228a6ae0f83b868101127b/assets
  ...
  ...
  ...
 /Users/dongkai/.gradle/caches/transforms-1/files-1.1/xray-preset-driver-0.14.0.aar/9572cdee5b909a644aeb66467819ae39/assets
 /Users/dongkai/Code/XiWeiLogistics/app_driver/build/generated/assets/shaders/release
 /Users/dongkai/Code/XiWeiLogistics/app_driver/src/main/assets
 /Users/dongkai/Code/XiWeiLogistics/app_driver/src/release/assets
outputs:
 /Users/dongkai/Code/XiWeiLogistics/app_driver/build/intermediates/incremental/mergeReleaseAssets
 /Users/dongkai/Code/XiWeiLogistics/app_driver/build/intermediates/assets/release
<------task end -------

输入文件:
所有的引用的lib或者module的assets内容
输出文件:
intermediates/assets/release ,内容为所有merge后的内容
intermediates/incremental/mergeReleaseAssets 输出merge过程中涉及到的assets目录

27.extractTryWithResourcesSupportJarRelease

将jdk1.7中try-with-resources语法糖jar包 libthrowable_extension.jar 打入到最终的包中
try-with-resources语法糖

源码分析

//com.android.build.gradle.internal.tasks.ExtractTryWithResourcesSupportJar
@TaskAction
    public void run() throws IOException {
        try (InputStream in =
                DesugarProcessBuilder.class
                        .getClassLoader()
                        .getResourceAsStream("libthrowable_extension.jar")) {
            FileUtils.cleanOutputDir(outputLocation.getSingleFile().getParentFile());
            Files.copy(in, outputLocation.getSingleFile().toPath());
        }
    }

其中源文件在打包插件 com.android.tools.build:gradle:3.1.4 的jar包中

输入输出

-----task begin-------->
project:     project ':app_driver' 
name:        extractTryWithResourcesSupportJarRelease 
group:       null 
description: null
conv:        [:]
inputs:
outputs:
 /Users/dongkai/Code/XiWeiLogistics/app_driver/build/intermediates/processing-tools/runtime-deps/release/desugar_try_with_resources.jar
<------task end -------

28.transformClassesWithStackFramesFixerForRelease

将所有的jar和class文件 利用asm 重新计算 堆栈信息,保证能够在JVM里正常运行。

源码分析

//com.android.build.gradle.internal.transforms.FixStackFramesTransform
/**
 * When running Desugar, we need to make sure stack frames information is valid in the class files.
 * This is due to fact that Desugar may load classes in the JVM, and if stack frame information is
 * invalid for bytecode 1.7 and above, {@link VerifyError} is thrown. Also, if stack frames are
 * broken, ASM might be unable to read those classes.
 *
 * <p>This transform will load all class files from all external jars, and will use ASM to
 * recalculate the stack frames information. In order to obtain new stack frames, types need to be
 * resolved.
 *
 * <p>This transform requires external libraries as inputs, and all other scope types are
 * referenced. Reason is that loading a class from an external jar, might depend on loading a class
 * that could be located in any of the referenced scopes. In case we are unable to resolve types,
 * content of the original class file will be copied to the the output as we do not know upfront if
 * Desugar will actually load that type.

输入输出

-----task begin-------->
project:     project ':app_driver' 
name:        transformClassesWithStackFramesFixerForRelease 
group:       null 
description: null
conv:        [:]
inputs:
 /Users/dongkai/Android/sdk/platforms/android-29/android.jar
 /Users/dongkai/Android/sdk/platforms/android-29/optional/org.apache.http.legacy.jar
 /Users/dongkai/Android/sdk/platforms/android-29/optional/android.test.mock.jar
 /Users/dongkai/Android/sdk/platforms/android-29/optional/android.test.base.jar
  ...
  ...
  ...
 /Users/dongkai/Code/XiWeiLogistics/biz_common/build/intermediates/intermediate-jars/release/classes.jar
 /Users/dongkai/.gradle/caches/modules-2/files-2.1/com.ymm.lib/lib_eversocket/2.2.3/1e1438faf1589ce0082832a759fadc4a3021919d/lib_eversocket-2.2.3.jar
 /Users/dongkai/Code/XiWeiLogistics/app_driver/build/intermediates/classes/release/pl/droidsonroids/gif/R.class
 /Users/dongkai/Code/XiWeiLogistics/app_driver/build/intermediates/classes/release/pl/droidsonroids/gif/R$styleable.class
  ...
  ...
  ...
 /Users/dongkai/Code/XiWeiLogistics/app_driver/build/intermediates/classes/release/com/ymm/lib/i_encrypt/R.class
 ...
 ...
 ...
 /Users/dongkai/Code/XiWeiLogistics/app_driver/build/intermediates/classes/release/com/wlqq/phantom/library/R$drawable.class
outputs:
 /Users/dongkai/Code/XiWeiLogistics/app_driver/build/intermediates/transforms/stackFramesFixer/release
<------task end -------

输入:
所有的jar包和class
输出:
/build/intermediates/transforms/stackFramesFixer/release

29.transformClassesWithDesugarForRelease

当我们选择JDK8以上版本时,有时候会使用lambda表达式,在设置android.enableD8.desugaring = false的时候。编译链会对lambda表达式进行一次脱糖处理

源码分析

// com.android.build.gradle.internal.transforms.DesugarTransform
整个就是desugar的过程,感兴趣的可以参考该类

输入输出

-----task begin-------->
project:     project ':app_driver' 
name:        transformClassesWithDesugarForRelease 
group:       null 
description: null
conv:        [:]
inputs:
 /Users/dongkai/Android/sdk/platforms/android-29/android.jar
 /Users/dongkai/Android/sdk/platforms/android-29/optional/org.apache.http.legacy.jar
 /Users/dongkai/Android/sdk/platforms/android-29/optional/android.test.mock.jar
 /Library/Java/JavaVirtualMachines/jdk1.8.0_77.jdk/Contents/Home/jre/lib/charsets.jar
 /Library/Java/JavaVirtualMachines/jdk1.8.0_77.jdk/Contents/Home/jre/lib/jfr.jar
 /Users/dongkai/Code/XiWeiLogistics/ymm_app_driver_main_module/build/intermediates/intermediate-jars/release/classes.jar
 /Users/dongkai/Code/XiWeiLogistics/biz_common/build/intermediates/intermediate-jars/release/classes.jar
...
...
...
 /Users/dongkai/Code/XiWeiLogistics/app_driver/build/intermediates/classes/release/com/wlqq/phantom/library/R$drawable.class
 /Users/dongkai/Code/XiWeiLogistics/app_driver/build/intermediates/transforms/stackFramesFixer/release/212.jar
 /Users/dongkai/Code/XiWeiLogistics/app_driver/build/intermediates/transforms/stackFramesFixer/release/206.jar
...
...
...
 /Users/dongkai/Code/XiWeiLogistics/app_driver/build/intermediates/transforms/stackFramesFixer/release/223.jar
 /Users/dongkai/Code/XiWeiLogistics/app_driver/build/intermediates/transforms/stackFramesFixer/release/237.jar
 /Users/dongkai/.gradle/caches/modules-2/files-2.1/com.ymm.lib/lib_eversocket/2.2.3/1e1438faf1589ce0082832a759fadc4a3021919d/lib_eversocket-2.2.3.jar
outputs:
 /Users/dongkai/Code/XiWeiLogistics/app_driver/build/intermediates/transforms/desugar/release
<------task end -------

输入:
所有的jar、class
输出:
目录/intermediates/transforms/desugar/release,内容是所有经过desugar的jar和class

30.processReleaseJavaRes

暂不清楚,处理内容,处理 java res ,MergeJavaResourcesTransform 会用到这个task的输出

源码分析

//com.android.build.gradle.tasks.factory.ProcessJavaResConfigAction
有这么一段注释
{@link Sync} task configured with {@link ProcessJavaResConfigAction} will sync all
source folders into a single folder identified by {@link VariantScope#getSourceFoldersJavaResDestinationDir()}
{@link MergeJavaResourcesTransform} will take the output of this merge plus the
dependencies and will create a single merge with the {@link PackagingOptions} settings
applied.

输入输出

-----task begin-------->
project:     project ':app_driver' 
name:        processReleaseJavaRes 
group:       null 
description: null
conv:        [:]
inputs:
outputs:
/Users/dongkai/Code/XiWeiLogistics/app_driver/build/intermediates/sourceFolderJavaResources/release
<------task end -------

这年头生活不易,人生不息,折腾不止!!!!

发表评论