gradle打包流程(三)--- 对gradle的深入分析

这篇文章主要讲下android gradle plugin主要流程

拿'com.android.application'来说,

1、准备工作

2、configureProject配置项目

3、configureExtension配置Extension

4、createTasksBeforeEvaluate创建不依赖flavor的task

5、createAndroidTasks创建构建task

1、准备工作

BasePlugin.apply()

(1)检查插件版本

(2)检查module是否重名

(3)初始化插件信息

之前我们自定义插件的时候,有定义一个xxx.properties文件,里面声明插件的入口类,而xxx就是apply plugin时使用的id,我们想要知道android gradle plugin的入口类,只需看com.android.application.properties文件即可,该文件位于:

 内容如下:

implementation-class=com.android.build.gradle.AppPlugin

这里定义了入口是AppPlugin。AppPlugin继承自BasePlugin。

AppPlugin主要是重写了createTaskManager和createExtension,剩下的大部分工作还是在BasePlugin里做的。

插件准备工作中的主要做的事情:

1、检查插件版本:

在BasePlugin的apply函数中执行了checkPluginVersion()

2、检查module是否重名

在BasePlugin的apply函数中执行了checkModuleForErrors()

3、初始化插件信息

在BasePlugin的apply函数中:

PluginInitializer.initialize(project, projectOptions);
ProfilerInitializer.init(project, projectOptions);
ProcessProfileWriter.getProject(project.getPath())
        .setAndroidPluginVersion(Version.ANDROID_GRADLE_PLUGIN_VERSION)
        .setAndroidPlugin(getAnalyticsPluginType())
        .setPluginGeneration(GradleBuildProject.PluginGeneration.FIRST);

2、配置项目 

BasePlugin.configureProject()

(1)检查gradle版本是否匹配

在BasePlugin的configureProject函数中执行了checkGradleVersion()

(2)创建AndroidBuilder和DataBindingBuilder:

在BasePlugin的configureProject函数中:

androidBuilder = new AndroidBuilder(
        project == project.getRootProject() ? project.getName() : project.getPath(),
        creator,
        new GradleProcessExecutor(project),
        new GradleJavaProcessExecutor(project),
        extraModelInfo,
        getLogger(),
        isVerbose());
dataBindingBuilder = new DataBindingBuilder();

(3)引入java plugin和jacoco plugin:

在BasePlugin的configureProject函数中:

project.getPlugins().apply(JavaBasePlugin.class);
project.getPlugins().apply(JacocoPlugin.class);

(4)设置构建完成以后的缓存清理工作:

在BasePlugin的configureProject函数中:

project.getGradle()
        .addBuildListener(
                new BuildListener() {
                    @Override
                    public void buildStarted(Gradle gradle) {
                        TaskInputHelper.enableBypass();
                    }

                    @Override
                    public void settingsEvaluated(Settings settings) {}

                    @Override
                    public void projectsLoaded(Gradle gradle) {}

                    @Override
                    public void projectsEvaluated(Gradle gradle) {}

                    @Override
                    public void buildFinished(BuildResult buildResult) {
                        // Do not run buildFinished for included project in composite build.
                        if (buildResult.getGradle().getParent() != null) {
                            return;
                        }
                        ExecutorSingleton.shutdown();
                        sdkHandler.unload();
                        threadRecorder.record(
                                ExecutionType.BASE_PLUGIN_BUILD_FINISHED,
                                project.getPath(),
                                null,
                                () -> {
                                    PreDexCache.getCache()
                                            .clear(
                                                    FileUtils.join(
                                                            project.getRootProject()
                                                                    .getBuildDir(),
                                                            FD_INTERMEDIATES,
                                                            "dex-cache",
                                                            "cache.xml"),
                                                    getLogger());
                                    Main.clearInternTables();
                                });
                    }
                });

如上所示,在BuildListener的buildFinished回调中做缓存清理工作。

3、配置Extension

BasePlugin.configureExtension()

(1)创建AppExtension,也就是build.gradle里用到的android{} dsl:

在BasePlugin的configureExtension函数中:

extension =
        createExtension(
                project,
                projectOptions,
                instantiator,
                androidBuilder,
                sdkHandler,
                buildTypeContainer,
                productFlavorContainer,
                signingConfigContainer,
                buildOutputs,
                extraModelInfo);

然后在AppPlugin中实现了createExtension,创建了android{} dsl

@NonNull
@Override
protected BaseExtension createExtension(
        @NonNull Project project,
        @NonNull ProjectOptions projectOptions,
        @NonNull Instantiator instantiator,
        @NonNull AndroidBuilder androidBuilder,
        @NonNull SdkHandler sdkHandler,
        @NonNull NamedDomainObjectContainer<BuildType> buildTypeContainer,
        @NonNull NamedDomainObjectContainer<ProductFlavor> productFlavorContainer,
        @NonNull NamedDomainObjectContainer<SigningConfig> signingConfigContainer,
        @NonNull NamedDomainObjectContainer<BaseVariantOutput> buildOutputs,
        @NonNull ExtraModelInfo extraModelInfo) {
    return project.getExtensions()
            .create(
                    "android",
                    AppExtension.class,
                    project,
                    projectOptions,
                    instantiator,
                    androidBuilder,
                    sdkHandler,
                    buildTypeContainer,
                    productFlavorContainer,
                    signingConfigContainer,
                    buildOutputs,
                    extraModelInfo);
}

 (2)创建依赖管理,ndk管理,任务管理,variant管理:

在BasePlugin的configureExtension函数的源码中可以找到,篇幅比较长,这里就不贴上了

(3)注册新增配置的回调函数,包括signingConfig,buildType,productFlavor:

在BasePlugin的configureExtension函数的源码中可以找到,篇幅比较长,这里就不贴上了

(4)创建默认的debug签名,创建debug和release两个buildType:

在BasePlugin的configureExtension函数中:

variantFactory.createDefaultComponents(
        buildTypeContainer, productFlavorContainer, signingConfigContainer);

ApplicationVariantFactory.java(实现了VariantFactory):

@Override
public void createDefaultComponents(
        @NonNull NamedDomainObjectContainer<BuildType> buildTypes,
        @NonNull NamedDomainObjectContainer<ProductFlavor> productFlavors,
        @NonNull NamedDomainObjectContainer<SigningConfig> signingConfigs) {
    // must create signing config first so that build type 'debug' can be initialized
    // with the debug signing config.
    signingConfigs.create(DEBUG);
    buildTypes.create(DEBUG);
    buildTypes.create(RELEASE);
}

4、创建不依赖flavor的task 

配置阶段完成之后,就开始创建构建需要的Task,是在BasePlugin.createTasks()里实现的,主要有两步:

  • UNINSTALL_ALL
  • DEVICE_CHECK
  • CONNECTED_CHECK
  • MAIN_PREBUILD
  • EXTRACT_PROGURAD_FILES
  • ASSEMBLE_ANDROID_TEST

这些task都是不需要依赖flavor数据的公共task。

5、创建构建task

BasePlugin.createAndroidTasks()

(1)生成flavors相关数据

(2)根据flavor创建相应的task

createAndroidTasks是在project.afterEvaluate里调用的。这个时候所有模块配置已经完成了,所以在这个阶段可以获取到对应的flavor以及其他配置了。

通过查看源码,我们可以得知:

在BasePlugin.createAndroidTasks里,是调用VariantManager.createAndroidTasks完成工作的。创建task的时候,会先通过populateVariantDataList生成flavor相关的数据结构,然后调用createTasksForVariantData创建flavor对应的task。

(1)populateVariantDataList

在这个方法里面,会先根据flavor和dimension创建对应的组合,存放在flavorComboList里,之后调用createVariantDataForProductFlavors创建对应的VariantData。

(2)createTasksForVariantData

创建完variant数据,就要给每个variantData创建对应的task。对应的task有assembleXXXTask,prebuildXXX,generateXXXSource,generateXXXResources,generateXXXAssets,processXXXManifest等等。

最后总结几点:

1、com.android.application对应的插件入口类是AppPlugin, com.android.library对应的插件入口类是LibraryPlugin

2、build.gradle里的android{} dsl是在BasePlugin.configureExtension()里声明的

3、主要的task是在BasePlugin.createAndroidTasks()里生成的

4、主要的task的实现可以在TaskManager中找到

猜你喜欢

转载自blog.csdn.net/zdj_Develop/article/details/122172441