添加Android Gradle插件作为运行时依赖项

时间:2015-09-24 08:40:59

标签: android plugins gradle dependencies runtime

我正在为Android编写Gradle插件,该插件使用新的Transform API。不幸的是,我遇到了添加Android插件作为我的插件的依赖项的问题。我的插件的简化Gradle配置如下所示:

插件/的build.gradle

apply plugin: "groovy"

dependencies {
    compile gradleApi()
    compile localGroovy()
    compile "com.android.tools.build:gradle:1.4.0-beta2"
}

这是使用我的Gradle插件的应用程序项目的简化配置:

应用/的build.gradle

buildscript {
    dependencies {
        classpath "com.android.tools.build:gradle:1.4.0-beta2"
        classpath "my-plugin:my-plugin:1.0.0"
    }
}

apply plugin: "com.android.application"
apply plugin: "my-plugin"

android {
    compileSdkVersion 23
    buildToolsVersion '23.0.1'

    defaultConfig {
        applicationId 'com.myapplication'
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 1
        versionName version
    }
}

使用此配置一切正常但我也希望我的插件能够正常使用以前版本的Android插件的项目。所以我尝试在我的应用程序的配置文件中更改Android插件版本:

application / build.gradle(使用Android插件1.3.1)

buildscript {
    dependencies {
        classpath "com.android.tools.build:gradle:1.3.1"
        classpath "my-plugin:my-plugin:1.0.0"
    }
}

/* Everything else is the same. */

但在这种情况下仍然使用Android插件1.4.0-beta2。我相信这是因为当Gradle解析类路径依赖关系时,它更喜欢1.4.0-beta2而不是1.3.1,因此整个项目开始使用Android插件的1.4.0-beta2版本。

我还尝试将Android插件添加为runtime依赖项,但在进行此更改后,我的插件停止编译,因为“无法解决”这样的错误:

Unable to resolve class com.android.build.gradle.api.BaseVariant @ line 19, column 1.
import com.android.build.gradle.api.BaseVariant

有没有办法针对最新版本的Android插件构建我的插件,但在运行时使用构建环境提供的Android插件版本?

1 个答案:

答案 0 :(得分:3)

最后,我设法通过手动添加provided范围来解决此问题。这是一篇关于将provided范围添加到Gradle的好文章:http://www.sinking.in/blog/provided-scope-in-gradle/。不幸的是,它没有解释如何使maven-publish插件处理provided范围。所以我要解释如何做到这一点。

在我的项目中,我在buildSrc中有一个小插件,负责发布到Maven。我将所有与provided相关的代码添加到此插件中,但可以将其添加到build.gradle文件中。

插件框架如下所示:

class PublishPlugin implements Plugin<Project> {
    private static final PROVIDED_CONFIGURATION_NAME = "provided"

    private Project project

    @Override
    void apply(final Project project) {
        project.apply plugin: 'java'
        project.apply plugin: 'maven-publish'
        project.apply plugin: 'com.jfrog.bintray'
        project.apply plugin: 'idea'

        addProvidedConfiguration()
        configureIdeaModule()

        project.afterEvaluate {
            modifyPomDependencyScopes()
        }
    }

然后我们创建一个provided范围。在编译期间可以使用随此范围添加的依赖项。在生成的pom.xml文件中,这些依赖项将具有provided范围。

    private void addProvidedConfiguration() {
        final Configuration provided =
                addConfiguration(project.configurations,
                        PROVIDED_CONFIGURATION_NAME)
        final Javadoc javadoc =
                project.tasks.getByName(JavaPlugin.JAVADOC_TASK_NAME) as Javadoc
        javadoc.classpath = javadoc.classpath.plus(provided)
    }

    private static Configuration addConfiguration(
           final ConfigurationContainer configurations, final String name) {
        final Configuration compile =
                configurations.getByName(JavaPlugin.COMPILE_CONFIGURATION_NAME)
        final Configuration configuration = configurations.create(name)

        compile.extendsFrom(configuration)
        configuration.visible = false
        configuration.transitive = false

        configuration.allDependencies.all { final dependency ->
            configurations.default.exclude(
                    group: dependency.group, module: dependency.name)
        }

        return configuration
    }

我使用IntelliJ IDEA所以我需要让它理解&#39; provided范围。 private void configureIdeaModule() { project.idea.module { scopes.PROVIDED.plus += [project.configurations.provided] } } 。如果你使用它,你必须对Eclipse做同样的事情。

pom.xml

最后,我们需要更改生成的runtime文件中的范围。默认情况下,Gradle将所有依赖项的范围设置为compile。如有必要,以下代码会将其更改为provided private void modifyPomDependencyScopes() { modifyPomDependencyScope(JavaPlugin.COMPILE_CONFIGURATION_NAME) modifyPomDependencyScope(PROVIDED_CONFIGURATION_NAME) } private void modifyPomDependencyScope(final String scope) { project.publishing.publications.all { pom.withXml { final DependencySet dependencies = project.configurations.getByName(scope).allDependencies asNode().dependencies.'*'.findAll() { dependencies.find { it.name == node.artifactId.text() }.each { it.scope*.value = scope } } } } }

compile

那就是它。然后,您只需将此插件应用于需要发布到Maven的项目,并将依赖关系类型从provided更改为apply plugin: "groovy" apply plugin: "my-publish-plugin" dependencies { compile gradleApi() compile localGroovy() provided "com.android.tools.build:gradle:1.4.0-beta2" }

android:focusable="true"
android:focusableInTouchMode="true"
android:clickable="true"