如何使用“api”或“implementation”指令从gradle插件获取依赖项

时间:2017-10-18 12:58:59

标签: gradle android-gradle android-studio-3.0

背景:运行Android Studio 3.0-beta7并试图让一个javadoc任务适用于Android库(事实上,这首先不是一个现成的任务,这真的很奇怪),我管理根据我的需要调整不同问题的答案,最后得到这段代码(https://stackoverflow.com/a/46810617/1226020):

task javadoc(type: Javadoc) {
    failOnError false
    source = android.sourceSets.main.java.srcDirs
    // Also add the generated R class to avoid errors...
    // TODO: debug is hard-coded
    source += "$buildDir/generated/source/r/debug/"
    // ... but exclude the R classes from the docs
    excludes += "**/R.java"

    // TODO: "compile" is deprecated in Gradle 4.1, 
    // but "implementation" and "api" are not resolvable :(
    classpath += configurations.compile

    afterEvaluate {
        // Wait after evaluation to add the android classpath
        // to avoid "buildToolsVersion is not specified" error
        classpath += files(android.getBootClasspath())

        // Process AAR dependencies
        def aarDependencies = classpath.filter { it.name.endsWith('.aar') }
        classpath -= aarDependencies
        aarDependencies.each { aar ->
            System.out.println("Adding classpath for aar: " + aar.name)
            // Extract classes.jar from the AAR dependency, and add it to the javadoc classpath
            def outputPath = "$buildDir/tmp/exploded-aar/${aar.name.replace('.aar', '.jar')}"
            classpath += files(outputPath)

            // Use a task so the actual extraction only happens before the javadoc task is run
            dependsOn task(name: "extract ${aar.name}").doLast {
                extractEntry(aar, 'classes.jar', outputPath)
            }
        }
    }
}

// Utility method to extract only one entry in a zip file
private def extractEntry(archive, entryPath, outputPath) {
    if (!archive.exists()) {
        throw new GradleException("archive $archive not found")
    }

    def zip = new java.util.zip.ZipFile(archive)

    zip.entries().each {
        if (it.name == entryPath) {
            def path = new File(outputPath)

            if (!path.exists()) {
                path.getParentFile().mkdirs()

                // Surely there's a simpler is->os utility except
                // the one in java.nio.Files? Ah well...
                def buf = new byte[1024]
                def is = zip.getInputStream(it)
                def os = new FileOutputStream(path)
                def len

                while ((len = is.read(buf)) != -1) {
                    os.write(buf, 0, len)
                }
                os.close()
            }
        }
    }
    zip.close()
}

此代码尝试查找所有依赖项AAR:s,循环遍历它们并从中提取classes.jar,并将它们放入在javadoc生成期间添加到类路径的临时文件夹中。基本上尝试重现真正的旧的Android gradle插件用于“爆炸 - aar”。

但是,代码依赖于使用compile依赖项。使用Gradle 4.1推荐的apiimplementation将无效,因为这些无法从Gradle任务中解析。

问题:如何在使用apiimplementation指令时获取依赖关系列表。 configuration.api呈现“无法解决”的错误?

Bonus问题:有没有一种新的,更好的方法来为Android Studio 3.0创建一个不涉及100行解决方案的库的javadoc?

2 个答案:

答案 0 :(得分:0)

您可以等待合并:

https://issues.apache.org/jira/browse/MJAVADOC-450

基本上,当前的Maven Javadoc插件忽略了AAR等分类器。

答案 1 :(得分:0)

当您尝试回答this question时,我遇到了相同的问题,因为此错误消息使我无法解决实现依赖性:

Resolving configuration 'implementation' directly is not allowed

然后我发现此answer有一个解决方案,可以解决实现和api配置:

configurations.implementation.setCanBeResolved(true)

我不确定该解决方法有多脏,但是似乎可以解决javadocJar任务的问题。