本文链接:[使用IDEA开发Gradle插件 : 获取Android工程信息] http://blog.devwiki.net/index.php/2017/09/08/custom-gradle-plugin-get-android-info.html

转载请注明出处,谢谢.

0x01 概要

在前面一文使用IDEA开发Gradle插件 : 开发基本过程中讲解了如何建立Gradle 插件工程并进行简单的开发和使用.今天则进行第二步,获取Android Studio工程的基本信息,包括:

  • buildToolsVersion
  • compileSdkVersion, minSdkVersion, targetSdkVersion
  • applicationId
  • versionCode, versionName

等等

0x02 添加依赖库

在获取项目信息时需要知道这些信息存放在哪里.通过执行以下代码可得到Android Application插件的类信息:

project.getPlugins().each {
    println "plugin:${it.class.name}"
}

结果如下:

plugin:com.android.build.gradle.LibraryPlugin
plugin:com.android.build.gradle.AppPlugin

由此去获得需要的依赖库信息:Maven Repository: com.android.tools.build » gradle或者这里The Central Repository Search Engine

按照说明添加依赖库,版本根据自己的项目选择.

compile group: 'com.android.tools.build', name: 'gradle', version: '2.2.3'

0x03 查看信息存放位置

通过

plugin:com.android.build.gradle.LibraryPlugin
plugin:com.android.build.gradle.AppPlugin

这段代码我们找到对应的插件信息:

public class AppPlugin extends BasePlugin implements Plugin<Project> {
    @Inject
    public AppPlugin(Instantiator instantiator, ToolingModelBuilderRegistry registry) {
        super(instantiator, registry);
    }
    @Override
    protected int getProjectType() {
        return AndroidProject.PROJECT_TYPE_APP;
    }

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

可得 AppPlugin是继承自 BasePlugin,查看BasePlugin代码:

public abstract class BasePlugin implements ToolingRegistryProvider {

    private static final GradleVersion GRADLE_MIN_VERSION = GradleVersion.parse("2.14.1");
    /** default retirement age in days since its inception date for RC or beta versions. */
    private static final int DEFAULT_RETIREMENT_AGE_FOR_NON_RELEASE_IN_DAYS = 40;


    protected BaseExtension extension;

    ...
}

可以得到 AppPlugin的扩展信息存在在BaseExtension里面.其源码如下:

public abstract class BaseExtension implements AndroidConfig {
    /** Secondary dependencies for the custom transform. */
    private final List<List<Object>> transformDependencies = Lists.newArrayList();

    private final AndroidBuilder androidBuilder;

    private final SdkHandler sdkHandler;

    private final ProductFlavor defaultConfig;

    private final AaptOptions aaptOptions;

    private final LintOptions lintOptions;

    private final ExternalNativeBuild externalNativeBuild;

    private final DexOptions dexOptions;

    private final TestOptions testOptions;

    private final CompileOptions compileOptions;

    private final PackagingOptions packagingOptions;

    private final JacocoOptions jacoco;

    private final Splits splits;

    private final AdbOptions adbOptions;

    private final NamedDomainObjectContainer<ProductFlavor> productFlavors;

    private final NamedDomainObjectContainer<BuildType> buildTypes;

    private final NamedDomainObjectContainer<SigningConfig> signingConfigs;

    private final List<DeviceProvider> deviceProviderList = Lists.newArrayList();

    private final List<TestServer> testServerList = Lists.newArrayList();

    private final List<Transform> transforms = Lists.newArrayList();

    private final DataBindingOptions dataBinding;

    private final NamedDomainObjectContainer<AndroidSourceSet> sourceSetsContainer;

    private String target;

    private Revision buildToolsRevision;

    private List<LibraryRequest> libraryRequests = Lists.newArrayList();

    private List<String> flavorDimensionList;

    private String resourcePrefix;

    private ExtraModelInfo extraModelInfo;

    private String defaultPublishConfig = "release";

    private boolean publishNonDefault = false;

    private Action<VariantFilter> variantFilter;

    protected Logger logger;

    private boolean isWritable = true;

    protected Project project;

    //...后面省略
}

通过源码可以看出,和Android配置的大部分信息均在此类中.且此类提供了相应的获取方法.

在Android 工程中的build.gradle 文件中,我们配置相关信息使用 android节点,从AppPlugin也能看出其 Extension的名称为android,所以获取方法如下:

def getInfo() {
    BaseExtension extension = project.extensions.getByName("android")
    println "buildToolsVersion:${extension.buildToolsVersion}"
    println "compileSdkVersion:${extension.getCompileSdkVersion()}"
    println "applicationId:${extension.defaultConfig.applicationId}"
    println "minSdkVersion:${extension.defaultConfig.minSdkVersion}"
    println "targetSdkVersion:${extension.defaultConfig.targetSdkVersion}"
    println "versionCode:${extension.defaultConfig.versionCode}"
    println "versionName:${extension.defaultConfig.versionName}"
}

0x04 执行获取代码

将以上代码放入 Task 类中,并重新打包 Gradle 插件,然后重新引用.最后运行Task,结果如下:

:watch:buildInfo
buildToolsVersion:22.0.1
compileSdkVersion:android-22
applicationId:com.xtc.watch
minSdkVersion:DefaultApiVersion{mApiLevel=14, mCodename='null'}
targetSdkVersion:DefaultApiVersion{mApiLevel=22, mCodename='null'}
versionCode:103
versionName:4.1.0.Local_J0_Gedb336d

由此可以获取Android的基本信息,其他更多信息,根据需要去获取.