携手创作,一起生长!这是我参与「日新方案 8 月更文应战」的第6天,点击检查活动概况>>
Hi,我是小余。
本文已收录到GitHub Androider-Planet中。这儿有 Android 进阶生长常识体系,关注公众号 [小余的自习室] ,在成功的路上不走失!
前语
前面几篇文章咱们解说了关于关于Gradle的根底
,Gradle生命周期
,Gradle相关Api
的解说,以及Gradle自定义插件
,Gradle Maven库房办理
.
Gradle系列文章如下:
Gradle筑基篇:
-
Gradle筑基篇(一)-Gradle初探
-
Gradle筑基篇(二)-Groovy语法的详解
-
Gradle筑基篇(三)-Gradle生命周期
-
Gradle筑基篇(四)-Gradle APi详解
-
Gradle筑基篇(五)-Gradle自定义插件实战
-
Gradle筑基篇(六)-Gradle Maven库房办理
Gradle进阶篇
- Gradle进阶篇(七)-AGP详解
今日这篇文章咱们来解说下Android Gradle Plugin
相关常识。
简化起见:本文所指
AGP
:Android Gradle Plugin
1.Gradle Plugin
和AGP
的差异?
Gradle Plugin
是Gradle
构建进程中运用的插件的总称,而Android Gradle Plugin
是这个总称里面的一个插件元素.
Android Gradle Plugin
合作Gradle
构建咱们的运用apk
2.apk构建流程
典型 Android 运用模块的构建流程。
依照以下常规进程履行:
- 1.将源文件和class文件编译组合后编译为dex文件
- 2.将资源文件转换为编译后的资源文件
- 3.将dex文件和编译后的资源文件打包为apk文件
- 4.运用签名东西对文件进行签名
- 5.生成最终apk之前,会运用 zipalign 东西对运用进行优化,减小apk运行时内存
在Gradle控制面板:履行assemble
使命看看:
Line 172: > Task :application:preBuild UP-TO-DATE //编译预处理使命:空完成
Line 176: > Task :application:preF1F3DebugBuild UP-TO-DATE //preF1F3DebugBuild F1F3变体预处理使命
Line 180: > Task :application:compileF1F3DebugAidl NO-SOURCE //编译aidl文件
Line 184: > Task :application:compileF1F3DebugRenderscript NO-SOURCE //编译制作脚本文件
Line 188: > Task :application:dataBindingMergeDependencyArtifactsF1F3Debug UP-TO-DATE //dataBinding依靠的类库或许插件兼并
Line 192: > Task :application:dataBindingMergeGenClassesF1F3Debug UP-TO-DATE //dataBinding依靠的class文件兼并
Line 196: > Task :application:generateF1F3DebugResValues UP-TO-DATE //生成ResValues
Line 200: > Task :application:generateF1F3DebugResources UP-TO-DATE//生成编译后的Resources
Line 204: > Task :application:mergeF1F3DebugResources UP-TO-DATE //兼并资源文件
Line 208: > Task :application:dataBindingGenBaseClassesF1F3Debug UP-TO-DATE
Line 212: > Task :application:dataBindingTriggerF1F3Debug UP-TO-DATE
Line 216: > Task :application:generateF1F3DebugBuildConfig UP-TO-DATE 生成BuildConfig文件
Line 220: > Task :application:javaPreCompileF1F3Debug UP-TO-DATE //java预编译
Line 224: > Task :application:checkF1F3DebugAarMetadata UP-TO-DATE //检测aar的元数据
Line 228: > Task :application:createF1F3DebugCompatibleScreenManifests UP-TO-DATE
Line 232: > Task :application:extractDeepLinksF1F3Debug UP-TO-DATE
Line 236: > Task :application:processF1F3DebugMainManifest UP-TO-DATE //处理MainManifest
Line 240: > Task :application:processF1F3DebugManifest UP-TO-DATE //处理Manifest
Line 244: > Task :application:processF1F3DebugManifestForPackage UP-TO-DATE//处理ManifestForPackage
Line 248: > Task :application:processF1F3DebugResources UP-TO-DATE//处理Resources
Line 252: > Task :application:compileF1F3DebugJavaWithJavac UP-TO-DATE //编译原代码为class文件
Line 256: > Task :application:compileF1F3DebugSources UP-TO-DATE//编译Sources
Line 260: > Task :application:mergeF1F3DebugNativeDebugMetadata NO-SOURCE
Line 264: > Task :application:mergeF1F3DebugShaders UP-TO-DATE
Line 268: > Task :application:compileF1F3DebugShaders NO-SOURCE
Line 272: > Task :application:generateF1F3DebugAssets UP-TO-DATE //生成Assets
Line 276: > Task :application:mergeF1F3DebugAssets UP-TO-DATE //兼并Assets
Line 280: > Task :application:compressF1F3DebugAssets UP-TO-DATE //紧缩Assets
Line 284: > Task :application:checkF1F3DebugDuplicateClasses UP-TO-DATE //检测DuplicateClasses
Line 288: > Task :application:desugarF1F3DebugFileDependencies UP-TO-DATE
Line 292: > Task :application:mergeExtDexF1F3Debug UP-TO-DATE //兼并des
Line 296: > Task :application:processF1F3DebugJavaRes NO-SOURCE //处理JavaRes
Line 300: > Task :application:mergeF1F3DebugJavaResource UP-TO-DATE //兼并JavaResource
Line 304: > Task :application:mergeLibDexF1F3Debug UP-TO-DATE //兼并lib的dex
Line 308: > Task :application:dexBuilderF1F3Debug UP-TO-DATE //dexBuilder
Line 312: > Task :application:mergeProjectDexF1F3Debug UP-TO-DATE//mergeProjectDex
Line 316: > Task :application:mergeF1F3DebugJniLibFolders UP-TO-DATE//兼并JniLibFolders
Line 320: > Task :application:mergeF1F3DebugNativeLibs UP-TO-DATE//兼并NativeLibs
Line 324: > Task :application:stripF1F3DebugDebugSymbols NO-SOURCE
Line 328: > Task :application:validateSigningF1F3Debug UP-TO-DATE //检测签名
Line 332: > Task :application:packageF1F3Debug UP-TO-DATE //打包变种
Line 336: > Task :application:assembleF1F3Debug UP-TO-DATE//打包变种
能够看到打包apk的使命根本和前面图片里面描述的流程一致,整个进程都是编译然后兼并,打包的进程
首要触及
:
- 1.资源文件。
- 2.源文件。
- 3.库文件的资源
- 4.库文件的class文件,
- 5.jni的静动态库信息,
- 6.manfest清单文件的创立
- 7.签名校验等 其他生成一些装备文件
3.AGP
常用设置类型:
- 1.
buildTypes
:编译类型:是debug或许release或许其他自定义类型
android {
defaultConfig {
manifestPlaceholders = [hostName:"www.example.com"]
...
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
applicationIdSuffix ".debug"
debuggable true
}
/**
* The `initWith` property allows you to copy configurations from other build types,
* then configure only the settings you want to change. This one copies the debug build
* type, and then changes the manifest placeholder and application ID.
*/
staging {
initWith debug
manifestPlaceholders = [hostName:"internal.example.com"]
applicationIdSuffix ".debugStaging"
}
}
}
- 2.
productFlavor
:产品变种
创立产品变种与创立 build
类型类似:将其添加到 build 装备中的 productFlavors 代码块并添加所需的设置。
产品变种支撑与 defaultConfig 相同的特点,这是因为,defaultConfig 实际上归于 ProductFlavor 类。
这意味着,您能够在 defaultConfig 代码块中提供一切变种的根本装备,每个变种均可更改其中任何默认值,如 applicationId
// Specifies one flavor dimension.
flavorDimensions 'abi','version'
productFlavors {
f1 {
dimension 'abi'
versionName '1.0'
}
f2 {
dimension 'abi'
versionName '2.0'
}
f3 {
dimension 'version'
}
f4 {
dimension 'version'
}
}
对应的变体:
- 3.build 变体
build 变体是 build 类型与产品变种的穿插产物,也是 Gradle 用来构建运用的装备 如上面的类型,编译时可选变体类型:
- 4.清单 (
Manifest
) 条目
在装备清单中能够设置Manifest清单中给的装备信息,如
applicationId "com.example.myapp"
minSdkVersion 15
targetSdkVersion 24
versionCode 1
versionName "1.0"
这些信息能够单独装备在不同给的变种中:如上面的类型,编译时可选变体类型: 这样能够针对不同变体设置不同的清单Manifest信息:
productFlavors {
f1 {
dimension 'abi'
applicationId "com.example.myapp"
minSdkVersion 15
targetSdkVersion 24
versionCode 1
versionName "1.0"
}
f2 {
dimension 'x86'
applicationId "com.example.myapp1"
minSdkVersion 16
targetSdkVersion 25
versionCode 2
versionName "2.0"
}
}
装备清单中信息会覆盖原Manifest文件中的信息,当有多个清单装备时会兼并 兼并东西会依据每个清单文件的优先级按次序兼并,将一切清单文件组合到一个文件中。 例如,假如您有三个清单文件,则会先将优先级最低的清单兼并到优先级第二高的清单中, 然后再将兼并后的清单兼并到优先级最高的清单中,如图:
- 5.
sourceSets
:原文件文件目录
sourceSets {
main {
java {
srcDirs = ['src/main/java']
}
res {
srcDirs = ['src/main/res']
}
aidl {
srcDirs = ['src/main/aidl']
}
}
}
- 6.
signingConfigs
:签名
Android 体系要求一切 APK 必须先运用证书进行数字签名,然后才能安装到设备上或进行更新
signingConfigs {
release {
storeFile file("myreleasekey.keystore")
storePassword "password"
keyAlias "MyReleaseKey"
keyPassword "password"
}
}
- 7.
compileOptions
:指定当时编译的java版别信息
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
- 7.
buildFeatures
:编译特色特点
buildFeatures {
aidl = true
buildConfig = true
viewBinding = false
dataBinding = true
}
//这个方法已经被弃用,后边源码能够看到弃用的当地
dataBinding {
enabled = true
}
以上便是咱们运用AGP时常用的插件装备项
下面咱们从源码去看下AGP插件
内部原理。
4.AGP插件
内部原理
1.源码检查办法
因为AGP插件源码大概有30多个g。所以不建议直接下载源码去阅读 能够直接在模块中引进就能够:
- 1.创立一个lib模块:
- 2.修改build.gradle中的代码:
apply plugin: 'java'
sourceCompatibility = 1.8
dependencies {
implementation gradleApi()
implementation 'com.android.tools.build:gradle:4.1.1'
}
同步代码后:能够在‘External Libraries
’中检查源码:
2.检查源码
前面在解说Gradle自定义插件
的时分,说过,咱们运用的每个插件都会在resources
中进行声明:
大局搜索:
找到implementation-class=com.android.build.gradle.AppPlugin
进入AppPlugin看看:
/**
* The plugin applied with `com.android.application'
*/
@Suppress("DEPRECATION")
class AppPlugin: BasePlugin() {
override fun apply(project: Project) {
super.apply(project)
project.apply(INTERNAL_PLUGIN_ID)
}
}
private val INTERNAL_PLUGIN_ID = mapOf("plugin" to "com.android.internal.application")
看到这儿运用的INTERNAL_PLUGIN_ID
中的plugin
:com.android.internal.application
咱们再次大局搜索下:com.android.internal.application
找到implementation-class=com.android.build.gradle.internal.plugins.AppPlugin
进入:com.android.build.gradle.internal.plugins.AppPlugin
gradle
源码:
查找apply办法:
在父类AbstractAppPlugin
的父类BasePlugin
找到了apply
办法:
public final void apply(@NonNull Project project) {
CrashReporting.runAction(
() -> {
//办法1
basePluginApply(project);
//办法2
pluginSpecificApply(project);
});
}
这儿咱们看办法1
:
private void basePluginApply(@NonNull Project project) {
// We run by default in headless mode, so the JVM doesn't steal focus.
System.setProperty("java.awt.headless", "true");
this.project = project;
//创立Project运行需求的服务信息
createProjectServices(project);
//获取Project的特点Options
ProjectOptions projectOptions = projectServices.getProjectOptions();
//依靠检测
DependencyResolutionChecks.registerDependencyCheck(project, projectOptions);
//AndroidBasePlugin内部是一个空完成,需求咱们自己去扩展。
project.getPluginManager().apply(AndroidBasePlugin.class);
//检测文件途径
checkPathForErrors();
//检测模块途径
checkModulesForErrors();
AttributionListenerInitializer.INSTANCE.init(
project, projectOptions.get(StringOption.IDE_ATTRIBUTION_FILE_LOCATION));
//agp的版别检测
AgpVersionChecker.enforceTheSamePluginVersions(project);
RecordingBuildListener buildListener = ProfilerInitializer.init(project, projectOptions);
//注册buildListener构建的监听逻辑
ProfileAgent.INSTANCE.register(project.getName(), buildListener);
threadRecorder = ThreadRecorder.get();
ProcessProfileWriter.getProject(project.getPath())
.setAndroidPluginVersion(Version.ANDROID_GRADLE_PLUGIN_VERSION)
.setAndroidPlugin(getAnalyticsPluginType())
.setPluginGeneration(GradleBuildProject.PluginGeneration.FIRST)
.setOptions(AnalyticsUtil.toProto(projectOptions));
/**
Gradle构建生命周期中的Agp插件的装备流程:
1.configureProject:构建project装备、
2.configureExtension:装备外部Extension字段
3.createTasks:创立Tasks
*/
threadRecorder.record(
ExecutionType.BASE_PLUGIN_PROJECT_CONFIGURE,
project.getPath(),
null,
this::configureProject);
threadRecorder.record(
ExecutionType.BASE_PLUGIN_PROJECT_BASE_EXTENSION_CREATION,
project.getPath(),
null,
this::configureExtension);
threadRecorder.record(
ExecutionType.BASE_PLUGIN_PROJECT_TASKS_CREATION,
project.getPath(),
null,
this::createTasks);
}
办法1首要使命:
- 做一些前期的检查工作,设置一些生命周期回调监听,创立使命等操作。
- Gradle构建生命周期中的Agp插件的装备流程:
1.
configureProject
:构建project装备、 2.configureExtension
:装备外部Extension字段 3.createTasks
:创立Tasks
看第一阶段:configureProject
private void configureProject() {
final Gradle gradle = project.getGradle();
//创立缓存版别变化的原因的字符串
Provider<ConstraintHandler.CachedStringBuildService> cachedStringBuildServiceProvider =
new ConstraintHandler.CachedStringBuildService.RegistrationAction(project)
.execute();
///** Build service used to cache maven coordinates for libraries. */
Provider<MavenCoordinatesCacheBuildService> mavenCoordinatesCacheBuildService =
new MavenCoordinatesCacheBuildService.RegistrationAction(
project, cachedStringBuildServiceProvider)
.execute();
new LibraryDependencyCacheBuildService.RegistrationAction(project).execute();
extraModelInfo = new ExtraModelInfo(mavenCoordinatesCacheBuildService);
ProjectOptions projectOptions = projectServices.getProjectOptions();
IssueReporter issueReporter = projectServices.getIssueReporter();
//创立Aapt2工作的构建Service
new Aapt2WorkersBuildService.RegistrationAction(project, projectOptions).execute();
//创立一个Aapt2 Daemon的构建Service
new Aapt2DaemonBuildService.RegistrationAction(project).execute();
new SyncIssueReporterImpl.GlobalSyncIssueService.RegistrationAction(
project, SyncOptions.getModelQueryMode(projectOptions))
.execute();
Provider<SdkComponentsBuildService> sdkComponentsBuildService =
new SdkComponentsBuildService.RegistrationAction(
project,
projectOptions,
project.getProviders()
.provider(() -> extension.getCompileSdkVersion()),
project.getProviders()
.provider(() -> extension.getBuildToolsRevision()),
project.getProviders().provider(() -> extension.getNdkVersion()),
project.getProviders().provider(() -> extension.getNdkPath()))
.execute();
projectOptions
.getAllOptions()
.forEach(projectServices.getDeprecationReporter()::reportOptionIssuesIfAny);
IncompatibleProjectOptionsReporter.check(
projectOptions, projectServices.getIssueReporter());
// Enforce minimum versions of certain plugins
GradlePluginUtils.enforceMinimumVersionsOfPlugins(project, issueReporter);
// Apply the Java plugin
project.getPlugins().apply(JavaBasePlugin.class);
dslServices =
new DslServicesImpl(
projectServices,
new DslVariableFactory(syncIssueReporter),
sdkComponentsBuildService);
MessageReceiverImpl messageReceiver =
new MessageReceiverImpl(
SyncOptions.getErrorFormatMode(projectOptions),
projectServices.getLogger());
//将前面创立的一切服务放到globalScope目标中
globalScope =
new GlobalScope(
project,
creator,
dslServices,
sdkComponentsBuildService,
registry,
messageReceiver,
componentFactory);
project.getTasks()
.named("assemble")
.configure(
task ->
task.setDescription(
"Assembles all variants of all applications and secondary packages."));
// As soon as project is evaluated we can clear the shared state for deprecation reporting.
gradle.projectsEvaluated(action -> DeprecationReporterImpl.Companion.clean());
createLintClasspathConfiguration(project);
}
- 这个办法首要是创立了一系列构建需求的服务,并将服务放到一个
globalScope
目标中,也算是一些前期准备工作。
来看阶段2:configureExtension
private void configureExtension() {
//获取dsl服务
DslServices dslServices = globalScope.getDslServices();
//获取构建输出
final NamedDomainObjectContainer<BaseVariantOutput> buildOutputs =
project.container(BaseVariantOutput.class);
project.getExtensions().add("buildOutputs", buildOutputs);
//创立变体的工厂类
variantFactory = createVariantFactory(projectServices, globalScope);
//将前面创立的几个目标都放入到variantInputModel目标中:
variantInputModel =
new LegacyVariantInputManager(
dslServices,
variantFactory.getVariantType(),
new SourceSetManager(
project,
isPackagePublished(),
dslServices,
new DelayedActionsExecutor()));
//这儿创立了外部扩展Extension,进入到这个办法看看
extension =
createExtension(
dslServices, globalScope, variantInputModel, buildOutputs, extraModelInfo);
globalScope.setExtension(extension);
variantManager =
new VariantManager<>(
globalScope,
project,
projectServices.getProjectOptions(),
extension,
variantFactory,
variantInputModel,
projectServices,
threadRecorder);
registerModels(
registry,
globalScope,
variantInputModel,
extension,
extraModelInfo);
// create default Objects, signingConfig first as its used by the BuildTypes.
variantFactory.createDefaultComponents(variantInputModel);
createAndroidTestUtilConfiguration();
}
进入createExtension
办法:
这个是抽象办法:具体完成是在子类AppPlugin中:
protected AppExtension createExtension(
@NonNull DslServices dslServices,
@NonNull GlobalScope globalScope,
@NonNull
DslContainerProvider<DefaultConfig, BuildType, ProductFlavor, SigningConfig>
dslContainers,
@NonNull NamedDomainObjectContainer<BaseVariantOutput> buildOutputs,
@NonNull ExtraModelInfo extraModelInfo) {
return project.getExtensions()
.create(
"android",
getExtensionClass(),
dslServices,
globalScope,
buildOutputs,
dslContainers.getSourceSetManager(),
extraModelInfo,
new ApplicationExtensionImpl(dslServices,
));
}
- 能够看到这儿创立了一个‘
android
’的Extensions
,bean类型为:BaseAppModuleExtension
这个BaseAppModuleExtension
类便是咱们能够在外部做扩展的起始点,这个类中有哪些特点包括父类中的特点都能够被扩展:
进到这个类中看看:
/** The `android` extension for base feature module (application plugin). */
open class BaseAppModuleExtension(...private val publicExtensionImpl: ApplicationExtensionImpl)
:AppExtension:InternalApplicationExtension by publicExtensionImpl,。。
看到该类承继了AppExtension和InternalApplicationExtension(被ApplicationExtensionImpl代理)
AppExtension又承继AbstractAppExtension承继TestedExtension承继BaseExtension 下面画出对应的类图联系
这几个类组成了AGP一切的对外扩展特点
这儿罗列几个平常项目中开发用到的字段:
- 1.在
ApplicationExtensionImpl
中:
buildFeatures
特点:
public open val buildFeatures:com.android.build.api.dsl.ApplicationBuildFeatures
检查ApplicationBuildFeatures中的代码:
内部就两条特点:
//用于dataBinding支撑
var dataBinding: Boolean?
var mlModelBinding: Boolean?
ApplicationBuildFeatures 承继 BuildFeatures
进入BuildFeatures
看看:
能够看到这儿面能够装备许多信息:
buildFeatures {
aidl = true
buildConfig = true
viewBinding = false
dataBinding = true
....
}
- 2.在AbstractAppExtension中
val applicationVariants: DomainObjectSet<ApplicationVariant> =
dslServices.domainObjectSet(ApplicationVariant::class.java)
这条特点,能够让咱们在外部获取到当时一切变种:
DomainObjectSet
是一个集合,能够运用集合遍历方法:
android.applicationVariants.all {variant->
variant.outputs.all {output->
outputFileName ="landi_dev_v${variant.versionName}_${variant.name}"+".apk"
}
}
相信这个代码我们在自己项目中或多或少都见过 通过前面分析咱们就知道:
variant = ApplicationVariant类目标
output = BaseVariantOutput类目标
关于configureExtension
就介绍到这
第3阶段:createTasks
private void createTasks() {
threadRecorder.record(
ExecutionType.TASK_MANAGER_CREATE_TASKS,
project.getPath(),
null,
() ->
TaskManager.createTasksBeforeEvaluate(
globalScope,
variantFactory.getVariantType(),
extension.getSourceSets()));
project.afterEvaluate(
CrashReporting.afterEvaluate(
p -> {
variantInputModel.getSourceSetManager().runBuildableArtifactsActions();
threadRecorder.record(
ExecutionType.BASE_PLUGIN_CREATE_ANDROID_TASKS,
project.getPath(),
null,
this::createAndroidTasks);
}));
}
- 1.BeforeEvaluate:装备前创立一些task
- 2.afterEvaluate:装备后创立一些task:进入createAndroidTasks看看:
final void createAndroidTasks() {
//运用variantManager创立变体 关注点1.。。
variantManager.createVariants();
//创立TaskManager 关注点2.。。
TaskManager<VariantT, VariantPropertiesT> taskManager =
createTaskManager(
variants,
variantManager.getTestComponents(),
!variantInputModel.getProductFlavors().isEmpty(),
globalScope,
extension,
threadRecorder);
//运用TaskManager创立使命:关注点3.。。
taskManager.createTasks();
//这儿设置Transforms的使命,假如外部有
new DependencyConfigurator(project, project.getName(), globalScope, variantInputModel)
.configureDependencySubstitutions()
.configureGeneralTransforms()
.configureVariantTransforms(variants, variantManager.getTestComponents());
for (ComponentInfo<VariantT, VariantPropertiesT> variant : variants) {
apiObjectFactory.create(variant.getProperties());
}
// lock the Properties of the variant API after the old API because
// of the versionCode/versionName properties that are shared between the old and new APIs.
variantManager.lockVariantProperties();
// Make sure no SourceSets were added through the DSL without being properly configured
variantInputModel.getSourceSetManager().checkForUnconfiguredSourceSets();
// configure compose related tasks.
taskManager.createPostApiTasks();
...
GradleProperty.Companion.endOfEvaluation();
}
看关注点1:variantManager.createVariants();
/** Creates the variants. */
public void createVariants() {
variantFactory.validateModel(variantInputModel);
variantFactory.preVariantWork(project);
computeVariants();
}
进入computeVariants:
/** Create all variants. */
private void computeVariants() {
//获取一切flavorDimension放到List中
List<String> flavorDimensionList = extension.getFlavorDimensionList();
//获取一切buildTypes和productFlavor信息:
DimensionCombinator computer =
new DimensionCombinator(
variantInputModel,
projectServices.getIssueReporter(),
flavorDimensionList);
//计算一切的变体
List<DimensionCombination> variants = computer.computeVariants();
//锁定变体
variantApiServices.lockValues();
}
关注点1首要作用便是获取一切的产品变体和buildTypes
,创立对应的变体列表
关注点2:createTaskManager
抽象办法在子类AppPlugin
中完成:
protected ApplicationTaskManager createTaskManager(
@NonNull
List<ComponentInfo<ApplicationVariantImpl, ApplicationVariantPropertiesImpl>>
variants,
@NonNull
List<
ComponentInfo<
TestComponentImpl<
? extends TestComponentPropertiesImpl>,
TestComponentPropertiesImpl>>
testComponents,
boolean hasFlavors,
@NonNull GlobalScope globalScope,
@NonNull BaseExtension extension,
@NonNull Recorder threadRecorder) {
return new ApplicationTaskManager(
variants, testComponents, hasFlavors, globalScope, extension, threadRecorder);
}
}
创立的是一个ApplicationTaskManager
类目标,后边会用到
来看关注点3:
这儿面其实便是创立一系列的task,篇幅太长,纷歧一介绍
阶段三:createTasks
首要使命:
- 1.依据
Extensions
中的信息创立一切变体, - 2.给一切变体创立对应的使命:包括装备前使命和装备后的使命
总结咱们的AGP
首要使命:
- 1.创立了一系列构建需求的服务,并将服务放到一个
globalScope
目标中,作为前期准备工作- 2.解析咱们的外部扩展android{}闭包中的信息,设置到Project中
- 3.依据buidTypes和产品变种创立对应的变种信息,创立一系列的构建使命。
参阅
-
Android构建官方文档
-
补齐Android技术树——从AGP构建进程到APK打包进程