我有一个很长的build.gradle
文件,它有我想要移入单独的.gradle
文件的函数以保持逻辑清洁。文档建议在这种情况下使用external build scripts。我在build.gradle
文件中有下一个功能:
android{
buildTypes {
debug {
signingConfig = loadFromPropertiesFile("DEBUG_KEY_PROPERTIES")
}
}
}
import com.android.builder.signing.DefaultSigningConfig
import com.android.builder.model.SigningConfig
SigningConfig loadFromPropertiesFile(keyProperty) {
// Load signing config from singning properties file
println keyProperty
println ("${keyProperty}")
if (project.hasProperty(keyProperty)) {
File releasePropsFile = new File(project.property(keyProperty))
println("Loading config from properties file: ${releasePropsFile}")
if (releasePropsFile.exists()) {
Properties releaseProps = new Properties()
releaseProps.load(new FileInputStream(releasePropsFile))
println releaseProps
def signingConfig = new DefaultSigningConfig(keyProperty)
signingConfig.storeFile = file(releasePropsFile.getParent() + "/" + releaseProps['keystore.file'])
signingConfig.storePassword = releaseProps['keystore.password']
//signingConfig.storeType = 'PKCS12'
signingConfig.keyAlias = releaseProps['alias.name']
signingConfig.keyPassword = releaseProps['alias.password']
return signingConfig
} else {
println("Can't read configuration file: ${releasePropsFile}")
return null
}
} else {
println("Project has not define configuration file: ${keyProperty}")
return null
}
}
代码逻辑并不重要,它放在build.gradle
文件时工作正常。但是当我将此方法移动到外部文件并将其包含在:
apply from: "$rootDir/gradle/android-signing.gradle"
我收到了下一个错误:
Cannot cast object 'DefaultSigningConfig{..}' with class
com.android.builder.signing.DefaultSigningConfig' to class
'com.android.builder.model.SigningConfig'
基本上它说它无法将实现强制转换为接口。因为DefaultSigningConfig实现了SigningConfig see here。这是没有意义的,直到我看到下一个answer。
两个类被视为完全不同的类,即使它们也是如此 有相同的包装和名称(甚至 实现/字段/方法)由不同的类加载器加载。 当您使用插件或外部构建脚本时就是这种情况。
但是,如何将build.gradle
中的方法拆分为模块化的单独文件?
答案 0 :(得分:0)
我发现(感谢,开源!)android插件DSL api不一致,让setter接受SigningConfig
接口,但强制getter强制转换为internal.dsl.SigningConfig
类。
所以它应该是这样的:
package com.android.builder.core;
import com.android.builder.internal.BaseConfigImpl;
import com.android.builder.model.BuildType;
import com.android.builder.model.SigningConfig;
public class DefaultBuildType extends BaseConfigImpl implements BuildType {
...
public BuildType setSigningConfig(SigningConfig signingConfig) {
mSigningConfig = signingConfig;
return this;
}
@Override
public SigningConfig getSigningConfig() {
return mSigningConfig;
}
}
但是然后BuiltTypeDSL强制转换为SigningConfigDSL类:
package com.android.build.gradle.internal.dsl
import com.android.builder.core.DefaultBuildType
/**
* DSL object to configure build types.
*/
public class BuildType extends DefaultBuildType implements Serializable {
...
/** The signing configuration. */
@Override
SigningConfig getSigningConfig() {
return (SigningConfig) super.signingConfig
}
}
请注意,两个方法getSigningConfig()
都具有相同名称SigningConfig
但包名称不同的返回类型。一个是接口com.android.builder.model.SigningConfig
,另一个是类com.android.build.gradle.internal.dsl.SigningConfig
,扩展com.android.builder.signing.DefaultSigningConfig
实现com.android.builder.model.SigningConfig
,这就是我的代码停止工作的地方,因为由于OOP原则,我们可以转换{{ 1}}到DefaultSigningConfig
接口,但不能将其强制转换为SigningConfig
类。
要使代码正常运行,我们可以创建internal.dsl.SigningConfig
而不是internal.dsl.SigningConfig
:
DefaultSigningConfig
或使用内部dsl模型包装import com.android.build.gradle.internal.dsl.SigningConfig
def signingConfig = new SigningConfig(keyProperty) // note that this is class which extends DefaultSigningConfig, not interface
signingConfig.storeFile = ... // same as before
signingConfig.storePassword = ...
signingConfig.keyAlias = ...
signingConfig.keyPassword = ...
return signingConfig
:
DefaultSigningConfig