Android构建流程——篇六
文章目錄
- Task17: javaPreCompileDebug
- 1. input/ouput
- 2. 驗(yàn)證
- 3. 核心類(JavaPreCompileTask)
- Task18:compileDebugJavaWithJavac
- 1. input/output
- 2. 核心類(AndroidJavaCompile)
- 3. AndroidJavaCompile
- Task19:compileDebugNdk
- 1. input/output
- 2. 核心類(NdkCompile)
- Task20:compileDebugSources
- Task21:mergeDebugShaders
- 1. input/ouput
- 2. 核心類(MergeSourceSetFolders)
- 2.1 MergeShaderSourceFoldersConfigAction.java
- 2.2 MergeSourceSetFolders.java
- Task22: compileDebugShaders
- 1. input/ouput
- 2. 核心類(ShaderCompile)
- 3. 調(diào)用路徑
- Task23: mergeDebugAssets
- 1. input/ouput
- 2. 核心類(MergeAppAssetConfigAction、MergeSourceSetFolders)
Task17: javaPreCompileDebug
1. input/ouput
taskName:javaPreCompileDebug input:/Users/apple/.gradle/caches/transforms-1/files-1.1/appcompat-v7-26.1.0.aar/2774ea4f1cf1e83a6ad8e8d3c8b463b6/jars/classes.jar input:/Users/apple/.gradle/caches/transforms-1/files-1.1/constraint-layout-1.1.3.aar/f43c0ba95b6494825ed940fc4f04662b/jars/classes.jar input:/Users/apple/.gradle/caches/transforms-1/files-1.1/animated-vector-drawable-26.1.0.aar/559112320064089dfaf6780e71d5b44f/jars/classes.jar input:/Users/apple/.gradle/caches/transforms-1/files-1.1/support-vector-drawable-26.1.0.aar/c2c3ad4abfd49316f6769b8238b0f010/jars/classes.jar input:/Users/apple/.gradle/caches/transforms-1/files-1.1/support-v4-26.1.0.aar/9ac5f97e8ccb24c52b7cbb6202c12ad0/jars/classes.jar input:/Users/apple/.gradle/caches/transforms-1/files-1.1/support-media-compat-26.1.0.aar/53ab5ad72634f3497309a8788f3ca200/jars/classes.jar input:/Users/apple/.gradle/caches/transforms-1/files-1.1/support-fragment-26.1.0.aar/7e6a4ce6591d722d47aafc36d980f8b4/jars/classes.jar input:/Users/apple/.gradle/caches/transforms-1/files-1.1/support-core-utils-26.1.0.aar/4c474caa9ac1f01c4936bd96905ecacd/jars/classes.jar input:/Users/apple/.gradle/caches/transforms-1/files-1.1/support-core-ui-26.1.0.aar/868eaa7e0c620cd85d72ad4f340e8bb1/jars/classes.jar input:/Users/apple/.gradle/caches/transforms-1/files-1.1/support-compat-26.1.0.aar/4ec3c1c46e5bad9ac3b91f45a2afec3e/jars/classes.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/com.android.support/support-annotations/26.1.0/814258103cf26a15fcc26ecce35f5b7d24b73f8/support-annotations-26.1.0.jar input:/Users/apple/.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:/Users/apple/.gradle/caches/transforms-1/files-1.1/runtime-1.0.0.aar/5b2333922ba05b1f174de51739b24d14/jars/classes.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/android.arch.lifecycle/common/1.0.0/e414a4cb28434e25c4f6aa71426eb20cf4874ae9/common-1.0.0.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/android.arch.core/common/1.0.0/a2d487452376193fc8c103dd2b9bd5f2b1b44563/common-1.0.0.jar ========================================================= output:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json從日志可以看出該任務(wù)是生成一個(gè)annotationProcessors.json文件,該文件記錄了主工程所依賴的注解處理器庫
2. 驗(yàn)證
在build.gradle添加
dataBinding {enabled = true }重新執(zhí)行打包,可以看到該json文件中記錄了databinding-compiler-3.2.0.jar
因?yàn)閐atabindg原理也是基于APT技術(shù)實(shí)現(xiàn),而其實(shí)現(xiàn)類就是記錄文件中的jar
3. 核心類(JavaPreCompileTask)
...@VisibleForTesting static final String DATA_BINDING_SPEC = "android.databinding.DataBinding";private static final String PROCESSOR_SERVICES ="META-INF/services/javax.annotation.processing.Processor";private File processorListFile;...@TaskAction public void preCompile() throws IOException {boolean grandfathered = annotationProcessorOptions.getIncludeCompileClasspath() != null;Collection<ResolvedArtifactResult> compileProcessors = null;if (!grandfathered) {// 1. 搜集compileClasspaths中涉及到注解處理器compileProcessors = collectAnnotationProcessors(compileClasspaths);FileCollection annotationProcessors =annotationProcessorConfiguration.getArtifactFiles();compileProcessors =compileProcessors.stream().filter(artifact -> !annotationProcessors.contains(artifact.getFile())).collect(Collectors.toList());// 如果發(fā)現(xiàn)編譯類路徑存在包含注解處理器的jar,則拋出異常// 此處新手集成butterknife經(jīng)常會(huì)遇到,原因是沒有使用annotationProcessor配置引用if (!compileProcessors.isEmpty()) {String message ="Annotation processors must be explicitly declared now. The following "+ "dependencies on the compile classpath are found to contain "+ "annotation processor. Please add them to the "+ annotationProcessorConfigurationName+ " configuration.\n - "+ Joiner.on("\n - ").join(convertArtifactsToNames(compileProcessors))+ "\nAlternatively, set "+ "android.defaultConfig.javaCompileOptions.annotationProcessorOptions.includeCompileClasspath = true "+ "to continue with previous behavior. Note that this option "+ "is deprecated and will be removed in the future.\n"+ "See "+ "https://developer.android.com/r/tools/annotation-processor-error-message.html "+ "for more details.";if (isTestComponent) {getLogger().warn(message);} else {throw new RuntimeException(message);}}}// Get all the annotation processors for metrics collection.Set<String> classNames = Sets.newHashSet();// 一般是讀取build.gralde中includeCompileClasspath屬性值,如果true,執(zhí)行掃描操作,開關(guān)打開會(huì)影響性能// 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. 搜集所有注解處理器// Add all annotation processors on the annotation processor configuration.classNames.addAll(convertArtifactsToNames(collectAnnotationProcessors(annotationProcessorConfiguration)));// 3. 存儲(chǔ)到集合中// Add the explicitly declared processors.// For metrics purposes, we don't care how they include the processor in their build.classNames.addAll(annotationProcessorOptions.getClassNames());// Add a generic reference to data binding, if present.if (dataBindingEnabled) {classNames.add(DATA_BINDING_SPEC);}// 3. 清理舊文件FileUtils.deleteIfExists(processorListFile);// 4. 寫文件Gson gson = new GsonBuilder().create();try (FileWriter writer = new FileWriter(processorListFile)) {gson.toJson(classNames, writer);} }可以看到該任務(wù)是遍歷所有jar,判斷jar中META-INF//services目錄中是否存在javax.annotation.processing.Processor文件,如果存在記錄下,并保存到j(luò)son文件中;注意下:JavaPreCompileTask只是繼承類AndroidBuilderTask類,并不支持增量更新操作,但帶有 Gradle-CacheableTask注解,所以其實(shí)是有緩存的,
/*** Returns a List of packages in the configuration believed to contain an annotation processor.** <p>We assume a package has an annotation processor if it contains the* META-INF/services/javax.annotation.processing.Processor file.*/private static List<ResolvedArtifactResult> collectAnnotationProcessors(ArtifactCollection configuration) {List<ResolvedArtifactResult> processors = Lists.newArrayList();for (ResolvedArtifactResult artifact : configuration) {File file = artifact.getFile();if (!file.exists()) {continue;}if (file.isDirectory()) {if (new File(file, PROCESSOR_SERVICES).exists()) {processors.add(artifact);}} else {try (JarFile jarFile = new JarFile(file)) {JarEntry entry = jarFile.getJarEntry(PROCESSOR_SERVICES);//noinspection VariableNotUsedInsideIfif (entry != null) {processors.add(artifact);}} catch (IOException iox) {// Can happen when we encounter a folder instead of a jar; for instance, in// sub-modules. We're just displaying a warning, so there's no need to stop the// build here.}}}return processors;}參考
- https://developer.android.com/studio/build/dependencies?utm_source=android-studio#annotation_processor
Task18:compileDebugJavaWithJavac
1. input/output
taskName:compileDebugJavaWithJavac input:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json input:/Users/apple/.gradle/caches/transforms-1/files-1.1/adapters-3.2.0.aar/49b3d7e4ab68d92f056ea8f56b33e9fb/jars/classes.jar input:/Users/apple/.gradle/caches/transforms-1/files-1.1/library-3.2.0.aar/818ffb3fe5dc5eeb6b4e51c93615b7fb/jars/classes.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/com.android.databinding/baseLibrary/3.2.0/fb5f8492c36231104cd86feaefa723291504c0a6/baseLibrary-3.2.0.jar input:/Users/apple/.gradle/caches/transforms-1/files-1.1/appcompat-v7-26.1.0.aar/2774ea4f1cf1e83a6ad8e8d3c8b463b6/jars/classes.jar input:/Users/apple/.gradle/caches/transforms-1/files-1.1/constraint-layout-1.1.3.aar/f43c0ba95b6494825ed940fc4f04662b/jars/classes.jar input:/Users/apple/.gradle/caches/transforms-1/files-1.1/support-v4-26.1.0.aar/9ac5f97e8ccb24c52b7cbb6202c12ad0/jars/classes.jar input:/Users/apple/.gradle/caches/transforms-1/files-1.1/support-fragment-26.1.0.aar/7e6a4ce6591d722d47aafc36d980f8b4/jars/classes.jar input:/Users/apple/.gradle/caches/transforms-1/files-1.1/support-core-utils-26.1.0.aar/4c474caa9ac1f01c4936bd96905ecacd/jars/classes.jar input:/Users/apple/.gradle/caches/transforms-1/files-1.1/animated-vector-drawable-26.1.0.aar/559112320064089dfaf6780e71d5b44f/jars/classes.jar input:/Users/apple/.gradle/caches/transforms-1/files-1.1/support-vector-drawable-26.1.0.aar/c2c3ad4abfd49316f6769b8238b0f010/jars/classes.jar input:/Users/apple/.gradle/caches/transforms-1/files-1.1/support-media-compat-26.1.0.aar/53ab5ad72634f3497309a8788f3ca200/jars/classes.jar input:/Users/apple/.gradle/caches/transforms-1/files-1.1/support-core-ui-26.1.0.aar/868eaa7e0c620cd85d72ad4f340e8bb1/jars/classes.jar input:/Users/apple/.gradle/caches/transforms-1/files-1.1/support-compat-26.1.0.aar/4ec3c1c46e5bad9ac3b91f45a2afec3e/jars/classes.jar input:/Users/apple/.gradle/caches/transforms-1/files-1.1/runtime-1.0.3.aar/5765c0929bc6bc40d70d6fc25f402f42/jars/classes.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/android.arch.lifecycle/common/1.0.3/7d7f60c4783872861222166f6164215f8951c7b1/common-1.0.3.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/android.arch.core/common/1.0.0/a2d487452376193fc8c103dd2b9bd5f2b1b44563/common-1.0.0.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/com.android.support/support-annotations/26.1.0/814258103cf26a15fcc26ecce35f5b7d24b73f8/support-annotations-26.1.0.jar input:/Users/apple/.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:/Users/apple/.gradle/caches/modules-2/files-2.1/androidx.databinding/databinding-compiler/3.2.0/765e0039a232d79ab0251a27665184f5546a5cdd/databinding-compiler-3.2.0.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/androidx.databinding/databinding-compiler-common/3.2.0/b73212517c2f1c275a38dc9623e78ed020d7d887/databinding-compiler-common-3.2.0.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/androidx.databinding/databinding-common/3.2.0/8908b4818c8f5add9fb9e33130135e96be1bb6ab/databinding-common-3.2.0.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre8/1.2.0/505f55b9619bbc5f5e26c77427dd24a6a441eef1/kotlin-stdlib-jre8-1.2.0.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/commons-io/commons-io/2.4/b1b6ea3b7e4aa4f492509a4952029cd8e48019ad/commons-io-2.4.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/commons-codec/commons-codec/1.9/9ce04e34240f674bc72680f8b843b1457383161a/commons-codec-1.9.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/org.antlr/antlr4/4.5.3/f35db7e4b2446e4174ba6a73db7bd6b3e6bb5da1/antlr4-4.5.3.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/com.googlecode.juniversalchardet/juniversalchardet/1.0.3/cd49678784c46aa8789c060538e0154013bb421b/juniversalchardet-1.0.3.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/com.google.guava/guava/23.0/c947004bb13d18182be60077ade044099e4f26f1/guava-23.0.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/com.squareup/javapoet/1.8.0/e858dc62ef484048540d27d36f3ec2177a3fa9b1/javapoet-1.8.0.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/com.android.tools.build.jetifier/jetifier-core/1.0.0-alpha10/9eb7027c383061de12f93aae7a22cbeb97832d2a/jetifier-core-1.0.0-alpha10.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/com.google.code.gson/gson/2.8.0/c4ba5371a29ac9b2ad6129b1d39ea38750043eff/gson-2.8.0.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/com.android.tools/annotations/26.2.0/e1c021729dcc35bfc5784a1def99021254f2d262/annotations-26.2.0.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jre7/1.2.0/ec8b969e26fbcf2265a4d1a1539c4d1d4c5af380/kotlin-stdlib-jre7-1.2.0.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.2.20/1ce9e25c74aade0aa039cce459f2906a8c8ffc8e/kotlin-stdlib-1.2.20.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/com.google.code.findbugs/jsr305/1.3.9/40719ea6961c0cb6afaeb6a921eaa1f6afd4cfdf/jsr305-1.3.9.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/com.google.errorprone/error_prone_annotations/2.0.18/5f65affce1684999e2f4024983835efc3504012e/error_prone_annotations-2.0.18.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/com.google.j2objc/j2objc-annotations/1.1/ed28ded51a8b1c6b112568def5f4b455e6809019/j2objc-annotations-1.1.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/org.codehaus.mojo/animal-sniffer-annotations/1.14/775b7e22fb10026eed3f86e8dc556dfafe35f2d5/animal-sniffer-annotations-1.14.jar input:/Users/apple/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/919f0dfe192fb4e063e7dacadee7f8bb9a2672a9/annotations-13.0.jar input:/Users/apple/work/project/AndroidGradleTaskDemo/app/src/main/java/com/gradle/task/demo/MainActivity.java input:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/generated/not_namespaced_r_class_sources/debug/processDebugResources/r/android/support/coreutils/R.java input:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/generated/not_namespaced_r_class_sources/debug/processDebugResources/r/android/support/v7/appcompat/R.java input:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/generated/not_namespaced_r_class_sources/debug/processDebugResources/r/android/support/compat/R.java input:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/generated/not_namespaced_r_class_sources/debug/processDebugResources/r/android/support/coreui/R.java input:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/generated/not_namespaced_r_class_sources/debug/processDebugResources/r/android/support/v4/R.java input:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/generated/not_namespaced_r_class_sources/debug/processDebugResources/r/android/support/fragment/R.java input:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/generated/not_namespaced_r_class_sources/debug/processDebugResources/r/android/support/graphics/drawable/R.java input:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/generated/not_namespaced_r_class_sources/debug/processDebugResources/r/android/support/graphics/drawable/animated/R.java input:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/generated/not_namespaced_r_class_sources/debug/processDebugResources/r/android/support/mediacompat/R.java input:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/generated/not_namespaced_r_class_sources/debug/processDebugResources/r/android/support/constraint/R.java input:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/generated/not_namespaced_r_class_sources/debug/processDebugResources/r/android/arch/lifecycle/R.java input:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/generated/not_namespaced_r_class_sources/debug/processDebugResources/r/com/gradle/task/demo/R.java input:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/generated/not_namespaced_r_class_sources/debug/processDebugResources/r/com/android/databinding/library/baseAdapters/R.java input:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/generated/not_namespaced_r_class_sources/debug/processDebugResources/r/com/android/databinding/library/R.java input:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/generated/source/buildConfig/debug/com/gradle/task/demo/BuildConfig.java input:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/generated/source/aidl/debug/com/gradle/task/demo/IHelloAidlInterface.java input:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/generated/source/dataBinding/trigger/debug/android/databinding/layouts/DataBindingInfo.java input:/Users/apple/Library/Android/sdk/platforms/android-26/android.jar input:/Users/apple/Library/Android/sdk/build-tools/28.0.2/core-lambda-stubs.jar input:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/intermediates/feature_data_binding_base_feature_info/debug/dataBindingExportFeaturePackageIdsDebug/out input:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/intermediates/data_binding_base_class_log_artifact/debug/dataBindingGenBaseClassesDebug/out input:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/intermediates/data_binding_dependency_artifacts/debug/dataBindingMergeDependencyArtifactsDebug/out input:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/intermediates/data_binding_layout_info_type_merge/debug/mergeDebugResources/out ========================================================= output:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/generated/source/apt/debug output:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes output:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/intermediates/data-binding/debug/bundle-bin該任務(wù)主要對Java源文件進(jìn)行編譯生成class字節(jié)碼文件操作
從日志可以看出該任務(wù)輸入包含以下幾種類型
輸出結(jié)果:
- apt工具生成的java類
- 輸入中所有java文件都會(huì)編譯成class文件(R.class、BuildConfig.class、 BR.class 、DataBinderMapperImpl.class等)
2. 核心類(AndroidJavaCompile)
JavaCompileConfigAction
該類中的execute方法主要是對AndroidJavaCompile任務(wù)做寫初始化,比如設(shè)置compileSdkVersion等
3. AndroidJavaCompile
AndroidJavaCompile任務(wù)比較簡單,就把源碼全部貼出來把。
可以看到AndroidJavaCompile類繼承了JavaCompile,它的任務(wù)主要是增加對java8兼容操作處理,編譯耗時(shí)記錄操作,創(chuàng)建apt的輸出目錄這三個(gè)動(dòng)作
/** Specialization of the JavaCompile task to record execution time. */ @CacheableTask public class AndroidJavaCompile extends JavaCompile {String compileSdkVersion;InstantRunBuildContext mInstantRunBuildContext;File annotationProcessorOutputFolder;BuildableArtifact processorListFile;String variantName;@PathSensitive(PathSensitivity.NONE)@InputFilespublic BuildableArtifact getProcessorListFile() {return processorListFile;}@OutputDirectorypublic File getAnnotationProcessorOutputFolder() {return annotationProcessorOutputFolder;}@Overrideprotected void compile(IncrementalTaskInputs inputs) {getLogger().info("Compiling with source level {} and target level {}.",getSourceCompatibility(),getTargetCompatibility());if (isPostN()) {// 1. 如果當(dāng)前編譯SDK版本大于N且與java8不兼容,直接拋出異常,沒怎么看明白if (!JavaVersion.current().isJava8Compatible()) {throw new RuntimeException("compileSdkVersion '" + compileSdkVersion + "' requires "+ "JDK 1.8 or later to compile.");}}processAnalytics();// Create directory for output of annotation processor.FileUtils.mkdirs(annotationProcessorOutputFolder);mInstantRunBuildContext.startRecording(InstantRunBuildContext.TaskType.JAVAC);// 2. 執(zhí)行java編譯操作super.compile(inputs);// 3. 記錄操作耗時(shí)mInstantRunBuildContext.stopRecording(InstantRunBuildContext.TaskType.JAVAC);}/** Read the processorListFile to add annotation processors used to analytics. */@VisibleForTestingvoid processAnalytics() {// 讀取所有注解處理器的庫的記錄文件(annotationProcessors.json),生成一個(gè)list列表Gson gson = new GsonBuilder().create();List<String> classNames;try (FileReader reader =new FileReader(BuildableArtifactUtil.singleFile(processorListFile))) {classNames = gson.fromJson(reader, new TypeToken<List<String>>() {}.getType());} catch (IOException e) {throw new UncheckedIOException(e);}// 保存注解處理器依賴庫編譯后續(xù)apt操作String projectPath = getProject().getPath();GradleBuildVariant.Builder variant =ProcessProfileWriter.getOrCreateVariant(projectPath, variantName);for (String processorName : classNames) {AnnotationProcessorInfo.Builder builder = AnnotationProcessorInfo.newBuilder();builder.setSpec(processorName);variant.addAnnotationProcessors(builder);}}@Internalprivate boolean isPostN() {final AndroidVersion hash = AndroidTargetHash.getVersionFromHash(compileSdkVersion);return hash != null && hash.getApiLevel() >= 24;} }Task19:compileDebugNdk
1. input/output
taskName:compileDebugNdk ========================================================= output:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/intermediates/ndk/debug/Android.mk output:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/intermediates/ndk/debug/obj output:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/intermediates/ndk/debug/lib該任務(wù)編譯NDK
官方NDK入門-https://developer.android.com/ndk/guides
2. 核心類(NdkCompile)
@TaskAction void taskAction(IncrementalTaskInputs inputs) throws IOException, ProcessException {FileTree sourceFileTree = getSource();Set<File> sourceFiles =sourceFileTree.matching(new PatternSet().exclude("**/*.h")).getFiles();File makefile = getGeneratedMakefile();if (isUseDeprecatedNdkFlag) {writeMakefile(sourceFiles, makefile);throw new RuntimeException(String.format("Error: Flag %s is no longer supported and will be removed in the next "+ "version of Android Studio. Please switch to a supported "+ "build system.\n%s",BooleanOption.ENABLE_DEPRECATED_NDK.getPropertyName(),getAlternativesAndLeaseNotice(makefile, "#ndkCompile")));}if (isDeprecatedNdkCompileLeaseExpired) {writeMakefile(sourceFiles, makefile);// Normally, we would catch the user when they try to configure the NDK, but NDK do// not need to be configured by default. Throw this exception during task execution in// case we miss it.throw new RuntimeException("Error: Your project contains C++ files but it is not using a supported "+ "native build system.\n"+ getAlternatives(null, ""));}if (sourceFiles.isEmpty()) {makefile.delete();FileUtils.cleanOutputDir(getSoFolder());FileUtils.cleanOutputDir(getObjFolder());return;}if (ndkDirectory == null || !ndkDirectory.isDirectory()) {throw new GradleException("NDK not configured.\n" +"Download the NDK from http://developer.android.com/tools/sdk/ndk/." +"Then add ndk.dir=path/to/ndk in local.properties.\n" +"(On Windows, make sure you escape backslashes, e.g. C:\\\\ndk rather than C:\\ndk)");}final ReferenceHolder<Boolean> generateMakeFile = ReferenceHolder.of(false);if (!inputs.isIncremental()) {getLogger().info("Unable do incremental execution: full task run");generateMakeFile.setValue(true);FileUtils.cleanOutputDir(getSoFolder());FileUtils.cleanOutputDir(getObjFolder());} else {// look for added or removed files *only*inputs.outOfDate(new Action<InputFileDetails>() {@Overridepublic void execute(InputFileDetails change) {if (change.isAdded()) {generateMakeFile.setValue(true);}}});inputs.removed(new Action<InputFileDetails>() {@Overridepublic void execute(InputFileDetails change) {generateMakeFile.setValue(true);}});}if (generateMakeFile.getValue()) {writeMakefile(sourceFiles, makefile);}getLogger().warn("Warning: Deprecated NDK integration enabled by "+ DEPRECATED_NDK_COMPILE_LEASE.getPropertyName()+ " flag in gradle.properties will be removed from Android Gradle "+ "plugin in the next version.\n"+ getAlternatives(makefile, "#ndkCompile"));// now buildrunNdkBuild(ndkDirectory, makefile); }從代碼可以看出主要做了二件事
Task20:compileDebugSources
沒找到這個(gè)任務(wù),感覺是個(gè)空任務(wù)
Task21:mergeDebugShaders
1. input/ouput
taskName:mergeDebugShaders input:/Users/apple/work/project/AndroidGradleTaskDemo/app/src/debug/shaders input:/Users/apple/work/project/AndroidGradleTaskDemo/app/src/main/shaders ========================================================= output:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/intermediates/incremental/mergeDebugShaders output:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/intermediates/shaders/debug2. 核心類(MergeSourceSetFolders)
2.1 MergeShaderSourceFoldersConfigAction.java
public static class MergeShaderSourceFoldersConfigAction extends ConfigAction {public MergeShaderSourceFoldersConfigAction(@NonNull VariantScope scope) {super(scope);}@NonNull@Overridepublic String getName() {return scope.getTaskName("merge", "Shaders");}@Overridepublic void execute(@NonNull MergeSourceSetFolders mergeAssetsTask) {super.execute(mergeAssetsTask);BaseVariantData variantData = scope.getVariantData();final GradleVariantConfiguration variantConfig = variantData.getVariantConfiguration();final Function<SourceProvider, Collection<File>> assetDirFunction =SourceProvider::getShadersDirectories;//設(shè)置一些入?yún)?#xff0c;和Task23類似,差異只是對應(yīng)任務(wù)的Config配置不同mergeAssetsTask.assetSetSupplier =() -> variantConfig.getSourceFilesAsAssetSets(assetDirFunction);mergeAssetsTask.sourceFolderInputs =() -> variantConfig.getSourceFiles(assetDirFunction);mergeAssetsTask.setOutputDir(scope.getMergeShadersOutputDir());}}2.2 MergeSourceSetFolders.java
@Override protected void doFullTaskAction() throws IOException {// this is full run, clean the previous outputFile destinationDir = getOutputDir();FileUtils.cleanOutputDir(destinationDir);List<AssetSet> assetSets = computeAssetSetList();// create a new merger and populate it with the sets.AssetMerger merger = new AssetMerger();try {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*/);// 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);}}Task22: compileDebugShaders
1. input/ouput
taskName:compileDebugShaders ========================================================= output:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/intermediates/shader_assets/debug/compileDebugShaders/out或許有人會(huì)compileDebugShaders不是應(yīng)該在Task21之前執(zhí)行嗎?怎么在之后?
我們可以從TaskManger.java類找到答案
代碼可以看到ShareCompile任務(wù)依賴mergeShadersTask
2. 核心類(ShaderCompile)
@CacheableTask public class ShaderCompile extends AndroidBuilderTask {private static final PatternSet PATTERN_SET = new PatternSet().include("**/*." + ShaderProcessor.EXT_VERT).include("**/*." + ShaderProcessor.EXT_TESC).include("**/*." + ShaderProcessor.EXT_TESE).include("**/*." + ShaderProcessor.EXT_GEOM).include("**/*." + ShaderProcessor.EXT_FRAG).include("**/*." + ShaderProcessor.EXT_COMP);@InputFiles@PathSensitive(PathSensitivity.RELATIVE)public FileTree getSourceFiles() {FileTree src = null;if (sourceDir.isDirectory()) {src = getProject().files(sourceDir).getAsFileTree().matching(PATTERN_SET);}return src == null ? getProject().files().getAsFileTree() : src;}@TaskActionprotected void compileShaders() throws IOException {// this is full run, clean the previous outputFile destinationDir = getOutputDir();FileUtils.cleanOutputDir(destinationDir);try {getBuilder().compileAllShaderFiles(sourceDir,getOutputDir(),defaultArgs,scopedArgs,ndkLocation,new LoggedProcessOutputHandler(getILogger()));} catch (Exception e) {throw new RuntimeException(e);}} }從代碼可以看出該任務(wù)就是掃描輸入路徑中所有如下格式文件進(jìn)行編譯
public static final String EXT_VERT = "vert"; public static final String EXT_TESC = "tesc"; public static final String EXT_TESE = "tese"; public static final String EXT_GEOM = "geom"; public static final String EXT_FRAG = "frag"; public static final String EXT_COMP = "comp";3. 調(diào)用路徑
#mermaid-svg-4dF0wV0KXAYGHb2L .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-4dF0wV0KXAYGHb2L .label text{fill:#333}#mermaid-svg-4dF0wV0KXAYGHb2L .node rect,#mermaid-svg-4dF0wV0KXAYGHb2L .node circle,#mermaid-svg-4dF0wV0KXAYGHb2L .node ellipse,#mermaid-svg-4dF0wV0KXAYGHb2L .node polygon,#mermaid-svg-4dF0wV0KXAYGHb2L .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-4dF0wV0KXAYGHb2L .node .label{text-align:center;fill:#333}#mermaid-svg-4dF0wV0KXAYGHb2L .node.clickable{cursor:pointer}#mermaid-svg-4dF0wV0KXAYGHb2L .arrowheadPath{fill:#333}#mermaid-svg-4dF0wV0KXAYGHb2L .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-4dF0wV0KXAYGHb2L .flowchart-link{stroke:#333;fill:none}#mermaid-svg-4dF0wV0KXAYGHb2L .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-4dF0wV0KXAYGHb2L .edgeLabel rect{opacity:0.9}#mermaid-svg-4dF0wV0KXAYGHb2L .edgeLabel span{color:#333}#mermaid-svg-4dF0wV0KXAYGHb2L .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-4dF0wV0KXAYGHb2L .cluster text{fill:#333}#mermaid-svg-4dF0wV0KXAYGHb2L div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-4dF0wV0KXAYGHb2L .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-4dF0wV0KXAYGHb2L text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-4dF0wV0KXAYGHb2L .actor-line{stroke:grey}#mermaid-svg-4dF0wV0KXAYGHb2L .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-4dF0wV0KXAYGHb2L .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-4dF0wV0KXAYGHb2L #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-4dF0wV0KXAYGHb2L .sequenceNumber{fill:#fff}#mermaid-svg-4dF0wV0KXAYGHb2L #sequencenumber{fill:#333}#mermaid-svg-4dF0wV0KXAYGHb2L #crosshead path{fill:#333;stroke:#333}#mermaid-svg-4dF0wV0KXAYGHb2L .messageText{fill:#333;stroke:#333}#mermaid-svg-4dF0wV0KXAYGHb2L .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-4dF0wV0KXAYGHb2L .labelText,#mermaid-svg-4dF0wV0KXAYGHb2L .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-4dF0wV0KXAYGHb2L .loopText,#mermaid-svg-4dF0wV0KXAYGHb2L .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-4dF0wV0KXAYGHb2L .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-4dF0wV0KXAYGHb2L .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-4dF0wV0KXAYGHb2L .noteText,#mermaid-svg-4dF0wV0KXAYGHb2L .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-4dF0wV0KXAYGHb2L .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-4dF0wV0KXAYGHb2L .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-4dF0wV0KXAYGHb2L .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-4dF0wV0KXAYGHb2L .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-4dF0wV0KXAYGHb2L .section{stroke:none;opacity:0.2}#mermaid-svg-4dF0wV0KXAYGHb2L .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-4dF0wV0KXAYGHb2L .section2{fill:#fff400}#mermaid-svg-4dF0wV0KXAYGHb2L .section1,#mermaid-svg-4dF0wV0KXAYGHb2L .section3{fill:#fff;opacity:0.2}#mermaid-svg-4dF0wV0KXAYGHb2L .sectionTitle0{fill:#333}#mermaid-svg-4dF0wV0KXAYGHb2L .sectionTitle1{fill:#333}#mermaid-svg-4dF0wV0KXAYGHb2L .sectionTitle2{fill:#333}#mermaid-svg-4dF0wV0KXAYGHb2L .sectionTitle3{fill:#333}#mermaid-svg-4dF0wV0KXAYGHb2L .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-4dF0wV0KXAYGHb2L .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-4dF0wV0KXAYGHb2L .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-4dF0wV0KXAYGHb2L .grid path{stroke-width:0}#mermaid-svg-4dF0wV0KXAYGHb2L .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-4dF0wV0KXAYGHb2L .task{stroke-width:2}#mermaid-svg-4dF0wV0KXAYGHb2L .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-4dF0wV0KXAYGHb2L .taskText:not([font-size]){font-size:11px}#mermaid-svg-4dF0wV0KXAYGHb2L .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-4dF0wV0KXAYGHb2L .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-4dF0wV0KXAYGHb2L .task.clickable{cursor:pointer}#mermaid-svg-4dF0wV0KXAYGHb2L .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-4dF0wV0KXAYGHb2L .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-4dF0wV0KXAYGHb2L .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-4dF0wV0KXAYGHb2L .taskText0,#mermaid-svg-4dF0wV0KXAYGHb2L .taskText1,#mermaid-svg-4dF0wV0KXAYGHb2L .taskText2,#mermaid-svg-4dF0wV0KXAYGHb2L .taskText3{fill:#fff}#mermaid-svg-4dF0wV0KXAYGHb2L .task0,#mermaid-svg-4dF0wV0KXAYGHb2L .task1,#mermaid-svg-4dF0wV0KXAYGHb2L .task2,#mermaid-svg-4dF0wV0KXAYGHb2L .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-4dF0wV0KXAYGHb2L .taskTextOutside0,#mermaid-svg-4dF0wV0KXAYGHb2L .taskTextOutside2{fill:#000}#mermaid-svg-4dF0wV0KXAYGHb2L .taskTextOutside1,#mermaid-svg-4dF0wV0KXAYGHb2L .taskTextOutside3{fill:#000}#mermaid-svg-4dF0wV0KXAYGHb2L .active0,#mermaid-svg-4dF0wV0KXAYGHb2L .active1,#mermaid-svg-4dF0wV0KXAYGHb2L .active2,#mermaid-svg-4dF0wV0KXAYGHb2L .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-4dF0wV0KXAYGHb2L .activeText0,#mermaid-svg-4dF0wV0KXAYGHb2L .activeText1,#mermaid-svg-4dF0wV0KXAYGHb2L .activeText2,#mermaid-svg-4dF0wV0KXAYGHb2L .activeText3{fill:#000 !important}#mermaid-svg-4dF0wV0KXAYGHb2L .done0,#mermaid-svg-4dF0wV0KXAYGHb2L .done1,#mermaid-svg-4dF0wV0KXAYGHb2L .done2,#mermaid-svg-4dF0wV0KXAYGHb2L .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-4dF0wV0KXAYGHb2L .doneText0,#mermaid-svg-4dF0wV0KXAYGHb2L .doneText1,#mermaid-svg-4dF0wV0KXAYGHb2L .doneText2,#mermaid-svg-4dF0wV0KXAYGHb2L .doneText3{fill:#000 !important}#mermaid-svg-4dF0wV0KXAYGHb2L .crit0,#mermaid-svg-4dF0wV0KXAYGHb2L .crit1,#mermaid-svg-4dF0wV0KXAYGHb2L .crit2,#mermaid-svg-4dF0wV0KXAYGHb2L .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-4dF0wV0KXAYGHb2L .activeCrit0,#mermaid-svg-4dF0wV0KXAYGHb2L .activeCrit1,#mermaid-svg-4dF0wV0KXAYGHb2L .activeCrit2,#mermaid-svg-4dF0wV0KXAYGHb2L .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-4dF0wV0KXAYGHb2L .doneCrit0,#mermaid-svg-4dF0wV0KXAYGHb2L .doneCrit1,#mermaid-svg-4dF0wV0KXAYGHb2L .doneCrit2,#mermaid-svg-4dF0wV0KXAYGHb2L .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-4dF0wV0KXAYGHb2L .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-4dF0wV0KXAYGHb2L .milestoneText{font-style:italic}#mermaid-svg-4dF0wV0KXAYGHb2L .doneCritText0,#mermaid-svg-4dF0wV0KXAYGHb2L .doneCritText1,#mermaid-svg-4dF0wV0KXAYGHb2L .doneCritText2,#mermaid-svg-4dF0wV0KXAYGHb2L .doneCritText3{fill:#000 !important}#mermaid-svg-4dF0wV0KXAYGHb2L .activeCritText0,#mermaid-svg-4dF0wV0KXAYGHb2L .activeCritText1,#mermaid-svg-4dF0wV0KXAYGHb2L .activeCritText2,#mermaid-svg-4dF0wV0KXAYGHb2L .activeCritText3{fill:#000 !important}#mermaid-svg-4dF0wV0KXAYGHb2L .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-4dF0wV0KXAYGHb2L g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-4dF0wV0KXAYGHb2L g.classGroup text .title{font-weight:bolder}#mermaid-svg-4dF0wV0KXAYGHb2L g.clickable{cursor:pointer}#mermaid-svg-4dF0wV0KXAYGHb2L g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-4dF0wV0KXAYGHb2L g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-4dF0wV0KXAYGHb2L .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-4dF0wV0KXAYGHb2L .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-4dF0wV0KXAYGHb2L .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-4dF0wV0KXAYGHb2L .dashed-line{stroke-dasharray:3}#mermaid-svg-4dF0wV0KXAYGHb2L #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-4dF0wV0KXAYGHb2L #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-4dF0wV0KXAYGHb2L #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-4dF0wV0KXAYGHb2L #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-4dF0wV0KXAYGHb2L #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-4dF0wV0KXAYGHb2L #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-4dF0wV0KXAYGHb2L #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-4dF0wV0KXAYGHb2L #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-4dF0wV0KXAYGHb2L .commit-id,#mermaid-svg-4dF0wV0KXAYGHb2L .commit-msg,#mermaid-svg-4dF0wV0KXAYGHb2L .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-4dF0wV0KXAYGHb2L .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-4dF0wV0KXAYGHb2L .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-4dF0wV0KXAYGHb2L g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-4dF0wV0KXAYGHb2L g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-4dF0wV0KXAYGHb2L g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-4dF0wV0KXAYGHb2L g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-4dF0wV0KXAYGHb2L g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-4dF0wV0KXAYGHb2L g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-4dF0wV0KXAYGHb2L .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-4dF0wV0KXAYGHb2L .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-4dF0wV0KXAYGHb2L .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-4dF0wV0KXAYGHb2L .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-4dF0wV0KXAYGHb2L .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-4dF0wV0KXAYGHb2L .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-4dF0wV0KXAYGHb2L .edgeLabel text{fill:#333}#mermaid-svg-4dF0wV0KXAYGHb2L .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-4dF0wV0KXAYGHb2L .node circle.state-start{fill:black;stroke:black}#mermaid-svg-4dF0wV0KXAYGHb2L .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-4dF0wV0KXAYGHb2L #statediagram-barbEnd{fill:#9370db}#mermaid-svg-4dF0wV0KXAYGHb2L .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-4dF0wV0KXAYGHb2L .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-4dF0wV0KXAYGHb2L .statediagram-state .divider{stroke:#9370db}#mermaid-svg-4dF0wV0KXAYGHb2L .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-4dF0wV0KXAYGHb2L .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-4dF0wV0KXAYGHb2L .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-4dF0wV0KXAYGHb2L .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-4dF0wV0KXAYGHb2L .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-4dF0wV0KXAYGHb2L .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-4dF0wV0KXAYGHb2L .note-edge{stroke-dasharray:5}#mermaid-svg-4dF0wV0KXAYGHb2L .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-4dF0wV0KXAYGHb2L .error-icon{fill:#522}#mermaid-svg-4dF0wV0KXAYGHb2L .error-text{fill:#522;stroke:#522}#mermaid-svg-4dF0wV0KXAYGHb2L .edge-thickness-normal{stroke-width:2px}#mermaid-svg-4dF0wV0KXAYGHb2L .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-4dF0wV0KXAYGHb2L .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-4dF0wV0KXAYGHb2L .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-4dF0wV0KXAYGHb2L .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-4dF0wV0KXAYGHb2L .marker{fill:#333}#mermaid-svg-4dF0wV0KXAYGHb2L .marker.cross{stroke:#333}:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}#mermaid-svg-4dF0wV0KXAYGHb2L {color: rgba(0, 0, 0, 0.75);font: ;}ShaderCompile.compileShadersAndroidBuilder.compileAllShaderFilesShaderProcessor.callLoggedProcessOutputHandler.handleOuputTask23: mergeDebugAssets
1. input/ouput
taskName:mergeDebugAssets input:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/intermediates/shader_assets/debug/compileDebugShaders/out input:/Users/apple/work/project/AndroidGradleTaskDemo/app/src/main/assets input:/Users/apple/work/project/AndroidGradleTaskDemo/app/src/debug/assets ========================================================= output:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/intermediates/incremental/mergeDebugAssets output:/Users/apple/work/project/AndroidGradleTaskDemo/app/build/intermediates/merged_assets/debug/mergeDebugAssets/out該任務(wù)掃描app中assets中所有資源,mergeDebugAssets目錄下的merger.xml記錄了合并的數(shù)據(jù)集合
mergeDebugAssets.out保存了合并的所有assets文件
2. 核心類(MergeAppAssetConfigAction、MergeSourceSetFolders)
public static class MergeAppAssetConfigAction extends MergeAssetBaseConfigAction {public MergeAppAssetConfigAction(@NonNull VariantScope scope) {super(scope, InternalArtifactType.MERGED_ASSETS, true);}@NonNull@Overridepublic String getName() {return scope.getTaskName("merge", "Assets");} } @CacheableTask public class MergeSourceSetFolders extends IncrementalTask {...@Overrideprotected void doFullTaskAction() throws IOException {// this is full run, clean the previous outputFile destinationDir = getOutputDir();FileUtils.cleanOutputDir(destinationDir);// 1. 計(jì)算app所有依賴的asset文件,存儲(chǔ)到列表中(主app中在最前面)List<AssetSet> assetSets = computeAssetSetList();// create a new merger and populate it with the sets.AssetMerger merger = new AssetMerger();try {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);// 2. 借用AssetMerger進(jìn)行asset文件合并處理merger.mergeData(writer, false /*doCleanUp*/);// 3. 生成merger.xml記錄文件// 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);}} }該任務(wù)和mergeDebugShaders邏輯流程相同,差異只是任務(wù)的input/ouput不同;
👇
Android構(gòu)建流程——上篇
Android構(gòu)建流程——下篇
總結(jié)
以上是生活随笔為你收集整理的Android构建流程——篇六的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android构建流程——篇五
- 下一篇: Android构建流程——篇七