Android构建流程——篇六
文章目录
- Task17: javaPreCompileDebug
- 1. input/ouput
- 2. 验证
- 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. 调用路径
- 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
从日志可以看出该任务是生成一个annotationProcessors.json文件,该文件记录了主工程所依赖的注解处理器库
2. 验证
在build.gradle添加
dataBinding {enabled = true
}
重新执行打包,可以看到该json文件中记录了databinding-compiler-3.2.0.jar
因为databindg原理也是基于APT技术实现,而其实现类就是记录文件中的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());// 如果发现编译类路径存在包含注解处理器的jar,则抛出异常// 此处新手集成butterknife经常会遇到,原因是没有使用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,执行扫描操作,开关打开会影响性能// 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. 存储到集合中// 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);}
}
可以看到该任务是遍历所有jar,判断jar中META-INF//services目录中是否存在javax.annotation.processing.Processor文件,如果存在记录下,并保存到json文件中;注意下:JavaPreCompileTask只是继承类AndroidBuilderTask类,并不支持增量更新操作,但带有 Gradle-CacheableTask注解,所以其实是有缓存的,
/*** 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
该任务主要对Java源文件进行编译生成class字节码文件操作
从日志可以看出该任务输入包含以下几种类型
- 依赖的第三方库(aar)中的jar文件
- App本身的java源文件
- App中包含的AIDL编译生成的java文件
- AAPT生成的R.java
- BuildConfig.java
- DataBinding生成的DataBindingInfo.java文件
- android.jar
输出结果:
- apt工具生成的java类
- 输入中所有java文件都会编译成class文件(R.class、BuildConfig.class、 BR.class 、DataBinderMapperImpl.class等)
2. 核心类(AndroidJavaCompile)
JavaCompileConfigAction
该类中的execute方法主要是对AndroidJavaCompile任务做写初始化,比如设置compileSdkVersion等
@Override
public void execute(@NonNull final AndroidJavaCompile javacTask) {scope.getTaskContainer().setJavacTask(javacTask);final GlobalScope globalScope = scope.getGlobalScope();final Project project = globalScope.getProject();BuildArtifactsHolder artifacts = scope.getArtifacts();boolean isDataBindingEnabled = globalScope.getExtension().getDataBinding().isEnabled();// 1. 设置compileSdkVersionjavacTask.compileSdkVersion = globalScope.getExtension().getCompileSdkVersion();javacTask.mInstantRunBuildContext = scope.getInstantRunBuildContext();// We can't just pass the collection directly, as the instanceof check in the incremental// compile doesn't work recursively currently, so every ConfigurableFileTree needs to be// directly in the source array.// 2. 添加java源文件路径for (ConfigurableFileTree fileTree: scope.getVariantData().getJavaSources()) {javacTask.source(fileTree);}javacTask.getOptions().setBootstrapClasspath(scope.getBootClasspath());FileCollection classpath = scope.getJavaClasspath(COMPILE_CLASSPATH, CLASSES);if (!globalScope.getProjectOptions().get(BooleanOption.ENABLE_CORE_LAMBDA_STUBS)&& scope.keepDefaultBootstrap()) {// adding android.jar to classpath, as it is not in the bootclasspath// 3. 编译需要依赖android framework相关API,所以需要添加classpath =classpath.plus(project.files(globalScope.getAndroidBuilder().getBootClasspath(false)));}javacTask.setClasspath(classpath);// 4. 设置java编译输出路径javacTask.setDestinationDir(artifacts.appendArtifact(InternalArtifactType.JAVAC, javacTask, "classes"));CompileOptions compileOptions = globalScope.getExtension().getCompileOptions();AbstractCompilesUtil.configureLanguageLevel(javacTask,compileOptions,globalScope.getExtension().getCompileSdkVersion(),scope.getJava8LangSupportType());javacTask.getOptions().setEncoding(compileOptions.getEncoding());Boolean includeCompileClasspath =scope.getVariantConfiguration().getJavaCompileOptions().getAnnotationProcessorOptions().getIncludeCompileClasspath();FileCollection processorPath =scope.getArtifactFileCollection(ANNOTATION_PROCESSOR, ALL, PROCESSED_JAR);if (Boolean.TRUE.equals(includeCompileClasspath)) {// We need the jar files because annotation processors require the resources.processorPath =processorPath.plus(scope.getJavaClasspath(COMPILE_CLASSPATH, PROCESSED_JAR));}javacTask.getOptions().setAnnotationProcessorPath(processorPath);boolean incremental = AbstractCompilesUtil.isIncremental(project,scope,compileOptions,null, /* processorConfiguration, JavaCompile handles annotation processor now */LOG);if (incremental) {LOG.verbose("Using incremental javac compilation for %1$s %2$s.",project.getPath(), scope.getFullVariantName());javacTask.getOptions().setIncremental(true);} else {LOG.verbose("Not using incremental javac compilation for %1$s %2$s.",project.getPath(), scope.getFullVariantName());}AnnotationProcessorOptions annotationProcessorOptions =scope.getVariantConfiguration().getJavaCompileOptions().getAnnotationProcessorOptions();if (!annotationProcessorOptions.getClassNames().isEmpty()) {javacTask.getOptions().getCompilerArgs().add("-processor");javacTask.getOptions().getCompilerArgs().add(Joiner.on(',').join(annotationProcessorOptions.getClassNames()));}if (!annotationProcessorOptions.getArguments().isEmpty()) {for (Map.Entry<String, String> arg :annotationProcessorOptions.getArguments().entrySet()) {javacTask.getOptions().getCompilerArgs().add("-A" + arg.getKey() + "=" + arg.getValue());}}javacTask.getOptions().getCompilerArgumentProviders().addAll(annotationProcessorOptions.getCompilerArgumentProviders());// 设置apt生成输出路径javacTask.getOptions().setAnnotationProcessorGeneratedSourcesDirectory(scope.getAnnotationProcessorOutputDir());javacTask.annotationProcessorOutputFolder = scope.getAnnotationProcessorOutputDir();// databinding相关配置if (isDataBindingEnabled) {// The data binding artifact is created through annotation processing, which is invoked// by the JavaCompile task. Therefore, we register JavaCompile as the generating task.artifacts.appendArtifact(InternalArtifactType.DATA_BINDING_ARTIFACT,ImmutableList.of(scope.getBundleArtifactFolderForDataBinding()),javacTask);}javacTask.processorListFile =artifacts.getFinalArtifactFiles(ANNOTATION_PROCESSOR_LIST);javacTask.variantName = scope.getFullVariantName();
}
3. AndroidJavaCompile
AndroidJavaCompile任务比较简单,就把源码全部贴出来把。
可以看到AndroidJavaCompile类继承了JavaCompile,它的任务主要是增加对java8兼容操作处理,编译耗时记录操作,创建apt的输出目录这三个动作
/** 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. 如果当前编译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. 执行java编译操作super.compile(inputs);// 3. 记录操作耗时mInstantRunBuildContext.stopRecording(InstantRunBuildContext.TaskType.JAVAC);}/** Read the processorListFile to add annotation processors used to analytics. */@VisibleForTestingvoid processAnalytics() {// 读取所有注解处理器的库的记录文件(annotationProcessors.json),生成一个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);}// 保存注解处理器依赖库编译后续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
该任务编译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);
}
从代码可以看出主要做了二件事
- writeMakefile(通过获取源native源文件,最终生成一个makefile)
- runNdkBuild (调用NDK工具包中ndk-build应用支持编译源文件)
Task20:compileDebugSources
没找到这个任务,感觉是个空任务
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/debug
2. 核心类(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;//设置一些入参,和Task23类似,差异只是对应任务的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
或许有人会compileDebugShaders不是应该在Task21之前执行吗?怎么在之后?
我们可以从TaskManger.java类找到答案
// TaskManger.java
public void createShaderTask(@NonNull VariantScope scope) {// merge the shader folders together using the proper priority.MergeSourceSetFolders mergeShadersTask =taskFactory.create(new MergeSourceSetFolders.MergeShaderSourceFoldersConfigAction(scope));// TODO do we support non compiled shaders in aars?//mergeShadersTask.dependsOn( scope.getVariantData().prepareDependenciesTask);// compile the shadersShaderCompile shaderCompileTask =taskFactory.create(new ShaderCompile.ConfigAction(scope));shaderCompileTask.dependsOn(mergeShadersTask);scope.getTaskContainer().getAssetGenTask().dependsOn(shaderCompileTask);
}
代码可以看到ShareCompile任务依赖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);}}
}
从代码可以看出该任务就是扫描输入路径中所有如下格式文件进行编译
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. 调用路径
Task23: 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
该任务扫描app中assets中所有资源,mergeDebugAssets目录下的merger.xml记录了合并的数据集合
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. 计算app所有依赖的asset文件,存储到列表中(主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进行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);}}
}
该任务和mergeDebugShaders逻辑流程相同,差异只是任务的input/ouput不同;
Android构建流程——篇六相关推荐
- Android构建流程——篇二
文章目录 预操作 任务列表 如何查看一个task类 Task1: checkDebugClasspath 1. input/output 2. 如何找到任务实现类 3. 核心类(AppClasspat ...
- Android构建流程——篇一
Android构建流程 前言 APK 构建流程 AGP(3.2.0)任务列表总览图 参考文献 前言 大家平时开发Android项目时一般都是点击AS run按钮,这样apk会自动安装到手机上,这整个过 ...
- Android构建流程——篇七
文章目录 Task24 transformClassesWithDexBuilderForDebug 1.input/ouput 2. 核心类(DexArchiveBuilderTransform,T ...
- Android构建流程——篇四
文章目录 Task9 generateDebugResValues 1. input/ouput 2. 核心类(GenerateResValues) Task10 generateDebugResou ...
- Android构建流程——篇五
文章目录 Task13: processDebugManifest 1. input/ouput 2. 整体流程 3. 调用链路 4. 核心类(MergeManifests) 5. AndroidBu ...
- Android构建流程——篇三
文章目录 Task5 checkDebugManifest 1. input/ouput 2. 核心类(CheckManifest) Task6 generateDebugBuildConfig 1. ...
- Android构建流程——篇八
文章目录 Task29 checkDebugLibraries 1. inut/ouput 2. 核心类(CheckMultiApkLibrariesTask) Task30 processDebug ...
- 指尖上的Android之实战篇(六)
本来准备周末看NBA,可是这两天都没比赛,要到礼拜一,悲吹的上班族 最近来感觉进步缓慢,难道是天气越来越热的缘故,开玩笑了,今天冒雨来公司加班,接着完善这个的项目的其他的功能模块. 今天说的模块是:查 ...
- 优酷 Android 构建速度优化实践
作者:苏彦郊(木磊) Android 项目一般使用 gradle 作为构建打包工具,gradle 简洁.动态的功能特性为人津津乐道,同样,构建执行速度缓慢的缺陷也一直为人诟病. 近年来,随着优酷功能特 ...
最新文章
- 程序猿真成猴了? | 每日趣闻
- 让自己的程序支持livewriter
- 找工作,我该如何是好?
- sublime-text3按tab跳出括号
- 国内ip信息库的组建
- 【译】你不知道的Chrome调试工具技巧 第七天:异步console的趣味小窍门
- python argparse(参数解析)模块学习(二)
- AD09导出光绘文件(Gerber)
- Linux切换jdk版本
- 农历和阳历日期互转,Python实现
- 主数据管理(MDM)与元数据管理
- android获取网络图片方法,Android获取网络图片并显示的方法
- p坚持csma协议 仿真‘_成都市与上海交通大学签署系列合作协议
- Linux:查看网络信息和网络监控命令。
- python 个性化推荐系统_如何在 Python 中使用 LightFM 构建可扩展的个性化推荐系统?...
- oracle 触发器 for each row 理解
- 写作之:syetem model和problem formulation
- Ubuntu 安装截图软件
- 一次buge寻找过程
- 一文读懂区块链隐私技术系列之佩德森承诺(Pedersen Commitment)以及应用
热门文章
- Android 蓝牙4.0(BLE)开发实现对蓝牙的写入数据和读取数据
- 五十八、2020美赛C题的思路以及个人Python的解法
- 5 多数据save_《Netlogo多主体建模入门》笔记 7
- Vue 学习第五天 学习笔记
- 北京内推 | 美团用户平台NLP中心招聘图学习(GNN)方向实习生
- 多模态中的Prompt范式:从CLIP、CoOp到CLIP-adapter
- 推荐系统去偏(Debiased Recommendation)研究进展概述
- 手把手带你掌握计算机视觉原始论文细节阅读
- 训练吞吐量提升6倍!飞桨弹性计算推荐系统套件ElasticCTR1.0发布
- 智源“高能对撞粒子分类挑战赛”开启,品鉴宇宙粒子的独特“味道”