这篇文章主要讲下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中找到