电子说
build 变体是 build 类型与产品变种的交叉产物,也是 Gradle 用来构建应用的配置
如上面的类型,编译时可选变体类型:
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文件中的信息,当有多个清单配置时会合并
合并工具会根据每个清单文件的优先级按顺序合并,将所有清单文件组合到一个文件中。
例如,如果您有三个清单文件,则会先将优先级最低的清单合并到优先级第二高的清单中,
然后再将合并后的清单合并到优先级最高的清单中,如图:
sourceSets
:原文件文件目录sourceSets {
main {
java {
srcDirs = ['src/main/java']
}
res {
srcDirs = ['src/main/res']
}
aidl {
srcDirs = ['src/main/aidl']
}
}
}
signingConfigs
:签名Android 系统要求所有 APK 必须先使用证书进行数字签名,然后才能安装到设备上或进行更新
signingConfigs {
release {
storeFile file("myreleasekey.keystore")
storePassword "password"
keyAlias "MyReleaseKey"
keyPassword "password"
}
}
compileOptions
:指定当前编译的java版本信息compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildFeatures
:编译特色属性buildFeatures {
aidl = true
buildConfig = true
viewBinding = false
dataBinding = true
}
//这个方式已经被弃用,后面源码可以看到弃用的地方
dataBinding {
enabled = true
}
以上就是我们使用AGP时常用的插件配置项
下面我们从源码去看下AGP插件
内部原理。
AGP插件
内部原理由于AGP插件源码大概有30多个g。所以不建议直接下载源码去阅读
可以直接在模块中引入就可以:
apply plugin: 'java'
sourceCompatibility = 1.8
dependencies {
implementation gradleApi()
implementation 'com.android.tools.build:gradle:4.1.1'
}
同步代码后:可以在‘External Libraries
’中查看源码:
前面在讲解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);
}
全部0条评论
快来发表一下你的评论吧 !