Android 探索之 Task 分析(二)

上一章节我们总结了apk打包的主要流程,那么从这一章节开始,我们开始看一下有哪些task,以及各task之间的依赖关系
声明本篇所有代码源码均参考 android build gradle 3.1.4版本,其他版本请对照分析。

有哪些task

我们在app的build.gradle中增加如下代码,输出执行一次打包有哪些task会被执行,其中该配置会输出 每个task执行的inputs和outputs方便后续分析task

Logger mLogger = new Logger("timeCoast",project);
gradle.taskGraph.afterTask { task ->;
    if(!task.project.getName().contains("app_driver")){
        return
    }
    StringBuffer taskDetails = new StringBuffer()
    taskDetails << """-----task begin-------->;
project:     $task.project 
name:        $task.name 
group:       $task.group 
description: $task.description
conv:        $task.convention.plugins
inputs:
"""
    task.inputs.files.each{ it ->;
        taskDetails << " ${it.absolutePath}\n"
    }
    taskDetails << "outputs:\n" 
    task.outputs.files.each{ it ->;
        taskDetails << " ${it.absolutePath}\n"
    }

    taskDetails << "<------task end -------"

    mLogger.log(taskDetails.toString());
}

class Logger {
    File mFile;
    Logger(String fileName,Project project) {
        mFile = new File(project.getRootDir(), String.format("%s-%s.txt", fileName,project.getName()));
        try {
            mFile.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    void clear() {
        if (mFile != null) {
            mFile.delete();
        }
    }
    void log(String text) {
        if (mFile != null) {
            FileWriter fw = null;
            try {
                fw = new FileWriter(mFile, true);
                fw.append(text + "\r\n");
            } catch (IOException var9) {
            } finally {
                if (fw != null) {
                    try {
                        fw.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

输出精简后的task执行顺序如下:

preBuild
extractProguardFiles
preReleaseBuild
compileReleaseAidl
compileReleaseRenderscript
checkReleaseManifest
generateReleaseBuildConfig
prepareLintJar
mainApkListPersistenceRelease
generateReleaseResValues
generateReleaseResources
mergeReleaseResources
createReleaseCompatibleScreenManifests
processReleaseManifest
splitsDiscoveryTaskRelease
processReleaseResources
generateReleaseSources
javaPreCompileRelease
compileReleaseJavaWithJavac
compileReleaseNdk
compileReleaseSources
lintVitalRelease
mergeReleaseShaders
compileReleaseShaders
generateReleaseAssets
mergeReleaseAssets
extractTryWithResourcesSupportJarRelease
transformClassesWithStackFramesFixerForRelease
transformClassesWithDesugarForRelease
processReleaseJavaRes
transformResourcesWithMergeJavaResForRelease
transformClassesAndResourcesWithProguardForRelease
transformClassesWithMultidexlistForRelease
transformClassesWithDexForRelease
mergeReleaseJniLibFolders
transformNativeLibsWithMergeJniLibsForRelease
validateSigningRelease
packageRelease
assembleRelease

依赖关系

我们同时也输出了task的依赖关系:

:app:assembleRelease
+--- :app:compileReleaseSources
|    +--- :app:compileReleaseJavaWithJavac
|    |    +--- :app:compileReleaseAidl
|    |    |    +--- :app:preReleaseBuild
|    |    |    |    +--- :app:extractProguardFiles
|    |    |    |    |    \--- :app:preBuild
|    |    |    |    +--- :app:preBuild *
|    |    +--- :app:compileReleaseRenderscript
|    |    |    +--- :app:preReleaseBuild *
|    |    +--- :app:generateReleaseBuildConfig
|    |    |    \--- :app:checkReleaseManifest
|    |    |         \--- :app:preReleaseBuild *
|    |    +--- :app:generateReleaseSources
|    |    |    +--- :app:compileReleaseAidl *
|    |    |    +--- :app:compileReleaseRenderscript *
|    |    |    +--- :app:generateReleaseBuildConfig *
|    |    |    +--- :app:prepareLintJar
|    |    |    \--- :app:processReleaseResources
|    |    |         +--- :app:mainApkListPersistenceRelease
|    |    |         +--- :app:mergeReleaseResources
|    |    |         |    +--- :app:generateReleaseResources
|    |    |         |    |    +--- :app:compileReleaseRenderscript *
|    |    |         |    |    \--- :app:generateReleaseResValues
|    |    |         +--- :app:processReleaseManifest
|    |    |         |    +--- :app:checkReleaseManifest *
|    |    |         |    +--- :app:createReleaseCompatibleScreenManifests
|    |    |         |    +--- :app:mainApkListPersistenceRelease *
|    |    |         +--- :app:splitsDiscoveryTaskRelease
|    |    +--- :app:javaPreCompileRelease
|    |    |    +--- :app:preReleaseBuild *
|    |    +--- :app:processReleaseResources *
|    \--- :app:compileReleaseNdk
|         \--- :app:preReleaseBuild *
+--- :app:lintVitalRelease
|    +--- :app:compileReleaseJavaWithJavac *
|    +--- :app:prepareLintJar *
|    +--- :app:processReleaseManifest *
\--- :app:packageRelease
     +--- :app:compileReleaseJavaWithJavac *
     +--- :app:mainApkListPersistenceRelease *
     +--- :app:mergeReleaseAssets
     |    +--- :app:compileReleaseShaders
     |    |    \--- :app:mergeReleaseShaders
     |    +--- :app:generateReleaseAssets
     |    |    \--- :app:compileReleaseShaders *
     +--- :app:processReleaseManifest *
     +--- :app:processReleaseResources *
     +--- :app:transformClassesAndResourcesWithProguardForRelease
     |    +--- :app:extractTryWithResourcesSupportJarRelease
     |    +--- :app:transformClassesWithDesugarForRelease
     |    |    +--- :app:compileReleaseJavaWithJavac *
     |    |    +--- :app:transformClassesWithStackFramesFixerForRelease
     |    |    |    +--- :app:compileReleaseJavaWithJavac *
     |    +--- :app:transformResourcesWithMergeJavaResForRelease
     |    |    +--- :app:compileReleaseJavaWithJavac *
     |    |    +--- :app:processReleaseJavaRes
     |    |    |    \--- :app:preReleaseBuild *
     +--- :app:transformClassesWithDexForRelease
     |    +--- :app:transformClassesAndResourcesWithProguardForRelease *
     |    \--- :app:transformClassesWithMultidexlistForRelease
     |         +--- :app:transformClassesAndResourcesWithProguardForRelease *
     +--- :app:transformNativeLibsWithMergeJniLibsForRelease
     |    +--- :app:compileReleaseNdk *
     |    +--- :app:mergeReleaseJniLibFolders
     |    |    \--- :app:generateReleaseAssets *
     \--- :app:validateSigningRelease

我们根据以上的依赖关系树,输出了一张依赖关系图,方便查看依赖关系

task组装

我们先来看下这些task是在什么地方创建并组装的,

VariantManager.createAssembleTaskForVariantData() // 创建 assembleXXXTask,此处会根据flavor等配置产生不同的variant
TaskManager.createTasksForVariantScope() // 是一个抽象类,具体实现在 ApplicationTaskManager.createTasksForVariantScope()

// createTasksForVariantScope 里的实现,如果在业务中有需要查看相关 task 源码时,可以来这里找
// com.android.build.gradle.internal.ApplicationTaskManager.java
void createTasksForVariantScope() {
    // 创建preBuild anchor task
    createAnchorTasks(variantScope); 
    // 检测manifest
    createCheckManifestTask(variantScope);
    //配置移动手表app
    handleMicroApp(variantScope);

    // Create all current streams (dependencies mostly at this point)
    createDependencyStreams(variantScope);
    // Add a task to publish the applicationId.
    createApplicationIdWriterTask(variantScope);  // application id 

    taskFactory.create(new MainApkListPersistence.ConfigAction(variantScope)); //主要的apk列表持久化
    // Add a task to 合并 manifest
    createMergeApkManifestsTask(variantScope); // 合并manifest
    // Add a task to create the res values 
    createGenerateResValuesTask(variantScope);  // 生成resvalue
    // Add a task to compile renderscript files.
    createRenderscriptTask(variantScope));   
    // Add a task to merge the resource folders
    createMergeResourcesTask(variantScope, true)); // 合并资源
    // Add tasks to compile shader
    createShaderTask(variantScope)); // 着色器 ,处理各种炫酷的图片效果等
    // Add a task to merge the asset folders
    createMergeAssetsTask(variantScope); // 合并assets
    // Add a task to create the BuildConfig class
    createBuildConfigTask(variantScope)); // 生成buildConfig
    // Add a task to process the Android Resources and generate source files
    createApkProcessResTask(variantScope);// 处理资源
    // Add a task to process the java resources
    createProcessJavaResTask(variantScope); // 处理java res
    createAidlTask(variantScope);//处理aidl
    createNdkTasks(variantScope) // 处理NDK
    // Add external native build tasks
    createExternalNativeBuildJsonGenerators(variantScope); 
    createExternalNativeBuildTasks(variantScope);    
    createMergeJniLibFoldersTasks(variantScope);// 合并 jni
    createDataBindingTasksIfNecessary(variantScope, MergeType.MERGE);// 处理 databinding
    addCompileTask(variantScope);//编译task  此处会调用到 createPostCompilationTasks(variantScope) 方法,此处会调用对应的方法将我们自定义的transform加入到其中
    createStripNativeLibraryTask(taskFactory, variantScope);
    createSplitTasks(variantScope);  // split apk task
    createPackagingTask(variantScope, buildInfoWriterTask); 打包apk
    createLintTasks(variantScope); // lint 
}
// createPostCompilationTasks 实现:
// 处理 Android Transform
void createPostCompilationTasks() {
    for (int i = 0, count = customTransforms.size(); i < count; i++) { Transform transform = customTransforms.get(i); 
// TransformManager.addTransform 实际上是为 transform 创建了一个 Task transformManager .addTransform(tasks, variantScope, transform) .ifPresent(t -> {
                    if (!deps.isEmpty()) {
                        t.dependsOn(tasks, deps);
                    }
                    // if the task is a no-op then we make assemble task depend on it.
                    if (transform.getScopes().isEmpty()) {
                        variantScope.getAssembleTask().dependsOn(tasks, t);
                    }
                });
    }
}

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

发表评论