Android 探索之 Task 分析(七)
本文将会分析如下几个task
generateReleaseAssets
mergeReleaseAssets
extractTryWithResourcesSupportJarRelease
transformClassesWithStackFramesFixerForRelease
transformClassesWithDesugarForRelease
processReleaseJavaRes
25.generateReleaseAssets
锚点task,参见TaskManager.createAnchorTasks
源码分析
输入输出
-----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 -------