如何将build.gradle逻辑拆分为更多.gradle文件?

时间:2014-11-12 10:25:52

标签: android gradle android-gradle build.gradle

我有一个很长的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中的方法拆分为模块化的单独文件?

1 个答案:

答案 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