首页 文章

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

提问于
浏览
2

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

plugin/build.gradle

apply plugin: "groovy"

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

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

application/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 (with Android plugin 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'错误而停止编译,如下所示:

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

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

1 回答

  • 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所以我需要使它成为'understand' provided 范围 . 如果使用Eclipse,则必须对Eclipse执行相同的操作 .

    private void configureIdeaModule() {
            project.idea.module {
                scopes.PROVIDED.plus += [project.configurations.provided]
            }
        }
    

    最后,我们需要更改生成的 pom.xml 文件中的范围 . 默认情况下,Gradle将所有依赖项的范围设置为 runtime . 如果需要,以下代码将它们更改为 compileprovided .

    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 }
                }
            }
        }
    }
    

    而已 . 然后,您只需将此插件应用于需要发布到Maven的项目,并将依赖关系类型从 compile 更改为 provided

    apply plugin: "groovy"
    apply plugin: "my-publish-plugin"
    
    dependencies {
        compile gradleApi()
        compile localGroovy()
        provided "com.android.tools.build:gradle:1.4.0-beta2"
    }
    

相关问题