Kotlin DSL中android.bootClasspath与android.sdkDirectory的替代方案及SdkComponents使用疑问
在Kotlin DSL里,android.sdkDirectory和android.bootClasspath这两个属性已经不存在了。
之前我用环境变量$ANDROID_HOME来替代android.sdkDirectory,写法是这样的:
val javadocs by tasks.registering(Javadoc::class) { val sdkDirectory = System.getenv("ANDROID_HOME") classpath = files(File("${sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar")) ... }
但对于android.bootClasspath,我还没找到合适的替代方案——原来的写法是这样的:
android.bootClasspath.forEach { classpath += fileTree(it) }
根据官方文档,现在有两个基于Provider<?>的API可以用,但我还搞不清楚具体怎么用:
- 怎么通过
Provider<?>的getSdkDirectory()来获取sdkDirectory? - 怎么通过
Provider<?>的getBootClasspath()来获取bootClasspath?
文档里有这样的说明:
The returned Provider can only be used at execution time and
therefore must be used as a org.gradle.api.Task input to do so.
现在我了解到可以通过android.sdkComponents来访问这两个属性:
val bootClasspath: Provider<List<RegularFile>> = android.sdkComponents.bootClasspath val sdkDirectory: Provider<Directory> = android.sdkComponents.sdkDirectory
但直接访问这些Provider的时候,会抛出这样的错误:
Unable to determine constructor argument #6: missing parameter of type
Provider, or no service of typeProvider<Provider<List<RegularFile>>>.
后来发现这个问题的原因是开启了android.newDsl=true;如果把这个参数设为false,原来的android.sdkDirectory和android.bootClasspath还能正常用,但此时android {}代码块已经被标记为废弃了。

虽然android {}可以用extensions.getByType<LibraryExtension>()来替代,但sdkComponents这个属性也已经被废弃了,官方建议改用AndroidComponents::sdkComponents或者对应的SdkComponents.kt实现。
在SdkComponents的说明里写着:
Build service used to load SDK components.
All build operations requiring access to the SDK components should declare it as input.
可我还是没搞明白,到底该怎么把它“声明为输入”呢?
备注:内容来源于stack exchange,提问作者Martin Zeitler

