一、利用 AS 查阅插件源码
本文参考的Android Gradle Plugin 的源码是 compile 'com.android.tools.build:gradle:2.3.0' Gradle 版本为 gradle-4.4
1.1、导入源码
- 1、新建一个AS项目
- 2、将 app/build.gradle 的内容修改为:
apply plugin: 'java'
dependencies {
compile gradleApi()
compile 'com.android.tools.build:gradle:2.3.0'
}
- 3、将根目录/build.gradle的插件修改为
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0'
}
二、Gradle 插件对 Android 的扩展
2.1 Gradle 插件 对 Application 的扩展
2.1.1 从 build.gradle 来看 android 配置
我们经常会在
build.gradle
文件中看到下面这段代码,那么你知道android
这个配置块为什么可以配置这么多属性吗?他们是怎么来的吗?下面我们从源码的角度来学习一下:
android {
compileSdkVersion 28
defaultConfig {
applicationId "extension.example.com.gradleext4android"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
首先,我们要明白 android
它是一个 Extension
,下面来看看源码就知道android
实际就是 AppExtension
这个类。所以 android
能配置什么属性就可以在 AppExtension
查找即可。
/**
* Gradle plugin class for 'application' projects.
*/
public class AppPlugin extends BasePlugin implements Plugin {
protected BaseExtension createExtension(
@NonNull Project project,
@NonNull Instantiator instantiator,
@NonNull AndroidBuilder androidBuilder,
@NonNull SdkHandler sdkHandler,
@NonNull NamedDomainObjectContainer buildTypeContainer,
@NonNull NamedDomainObjectContainer productFlavorContainer,
@NonNull NamedDomainObjectContainer signingConfigContainer,
@NonNull ExtraModelInfo extraModelInfo) {
return project.getExtensions()
.create(
"android",//"android" 就是 Extension 的名字
AppExtension.class,
project,
instantiator,
androidBuilder,
sdkHandler,
buildTypeContainer,
productFlavorContainer,
signingConfigContainer,
extraModelInfo);
}
2.1.2 AppExtension
我们从源码可以看到它最终是继承至 BaseExtension
这个类,我们在 android
中定义的 compileSdkVersion
,defaultConfig{}
,buildTypes
等就是在这个类定义的啦
public class AppExtension extends TestedExtension {}
public abstract class TestedExtension extends BaseExtension implements TestedAndroidConfig {}
从上面2.1.1
中可以知道可以知道,"android" 这个 Extension 是定义在 AppPlugin 中的,那么我们来看看 AppPlgin 是什么东西?
2.1.3 AppPlgin
从 AppPlugin
这个类的定义可以知道,它是一个插件,并且从注释'application'可以看出,这个插件是用于应用程序的项目,而非 Library 或者其它。
/**
* Gradle plugin class for 'application' projects.
*/
public class AppPlugin extends BasePlugin implements Plugin {
....
}
那这个 AppPlugin
是在哪里应用的呢?来看看下面的截图吧:
自定义过 Gradle Plugin
的同学就知道,implementation-class
声明了 AppPlugin
它会跟 com.android.application.properties(文件名)建立联系。
implementation-class=com.android.build.gradle.AppPlugin
apply plugin: 'com.android.application'
至此,我们就知道为什么在新建一个 application
的 module
时会 apply plugin: 'com.android.application'
的来源了。
2.2 Gradle 插件对 Library 的扩展
那么我们都知道,我们常用的除了 Application module之外,我们还会创建一个 Library
类型的 module
哦。 那么我们来看一下它的 build.gradle
是怎么配置的?
2.2.1 从 build.gradle 来看 android 配置
来,首先,我们新建一个 library
类型的 module
之后就可以看到以下这段脚本代码:
apply plugin: 'com.android.library'//应用library插件
android {
compileSdkVersion 26
defaultConfig {
minSdkVersion 15
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
咋一看,跟 Application Module 的脚本代码没啥太大的差异。
/**
* Gradle plugin class for 'library' projects.
*/
public class LibraryPlugin extends BasePlugin implements Plugin {}
从这段代码可以知道,它跟 AppPlugin 都有一个共同的父类 BasePlugin
,当然 BasePlugin
还有其他几个子类,我们现在只关心 AppPlugin
和 LibraryPlugin
这两兄弟。
从下面这段代码可以直到,它的 android
对应的 Extension
就是 LibraryExtension
这个类。
@NonNull
@Override
protected BaseExtension createExtension(
@NonNull Project project,
@NonNull Instantiator instantiator,
@NonNull AndroidBuilder androidBuilder,
@NonNull SdkHandler sdkHandler,
@NonNull NamedDomainObjectContainer buildTypeContainer,
@NonNull NamedDomainObjectContainer productFlavorContainer,
@NonNull NamedDomainObjectContainer signingConfigContainer,
@NonNull ExtraModelInfo extraModelInfo) {
return project.getExtensions()
.create(
"android",
LibraryExtension.class,
project,
instantiator,
androidBuilder,
sdkHandler,
buildTypeContainer,
productFlavorContainer,
signingConfigContainer,
extraModelInfo);
}
2.2.2 LibraryExtension
同理 LibraryExtension
跟 AppExtension
一样都是继承自 BaseExtension
哦,这就是为什么在 android
配置的东西都差不多的原因啦。
public class LibraryExtension extends TestedExtension {}
public abstract class TestedExtension extends BaseExtension implements TestedAndroidConfig {}
我们分析过 AppPlugin
是如何被定义和使用之后,那么 LibraryPlugin
也是一样的。
apply plugin: 'com.android.library'
总结
经过上面的分析,我们就知道原来 build.gradle 的 android
这个配置块是一个 Extension
来的,并且通过对源码的阅读,我们就可以知道怎么去定义 android
内部的一些属性。
记录于 2019年2月19日晚