2014-11-12 15 views
6

Ho un file lungo build.gradle con funzioni che voglio spostare in un file separato .gradle per mantenere la logica pulita. I documenti suggeriscono di utilizzare external build scripts per questo caso. Ho funzione successiva a build.gradle di file:Come suddividere la logica build.gradle in altri file .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 
    } 
} 

La logica di codice non importa, si sta lavorando bene quando è posto a build.gradle file. Ma non riesce quando mi muovo questo metodo per il file esterno e includerlo con:

apply from: "$rootDir/gradle/android-signing.gradle"

ho ottenuto prossimo errore:

Cannot cast object 'DefaultSigningConfig{..}' with class 
com.android.builder.signing.DefaultSigningConfig' to class 
'com.android.builder.model.SigningConfig' 

In sostanza si dice che non può lanciare implementazione all'interfaccia . Perché DefaultSigningConfig implementa SigningConfig see here. Il che non ha senso, fino a quando non vedo il prossimo answer.

Two classes are treated as entirely different classes, even if they have the same package and name (and even implementation/fields/methods) when loaded by different classloaders. Which is the case when you are using plugin or external build script.

Ma allora, come posso dividere i metodi da build.gradle in file separati modulari?

+0

quando si usa applicare da:? definisci solo il metodo loadFromPropertiesFile? se si desidera utilizzare la clausola android {} e le sue classi relative è necessario assicurarsi di aver applicato il plug-in Android PRIMA di eseguire l'applicazione! la domanda da è fondamentalmente simile all'inclusione eccetto che le variabili locali se definite non vengono trasmesse. – codeScriber

+0

@Sergii Pechenizkyi Hai mai lavorato su questo? –

risposta

0

Ho trovato (grazie, opensource!) Che il plugin Android DSL api è incoerente lasciando che il setter prenda l'interfaccia SigningConfig, ma costringendo il getter a trasmettere alla classe internal.dsl.SigningConfig.

Così dovrebbe essere simile a questo:

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

Ma poi la forza getto BuiltTypeDSL alla classe 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 
    } 
} 

Nota che entrambi i metodi getSigningConfig() hanno tipo restituito con lo stesso nome SigningConfig ma diversi packagename . Uno è l'interfaccia com.android.builder.model.SigningConfig e l'altra è com.android.builder.signing.DefaultSigningConfig che implementa com.android.builder.model.SigningConfig ed è qui che il mio codice smette di funzionare, perché a causa dei principi OOP possiamo trasmettere DefaultSigningConfig all'interfaccia SigningConfig, ma non possiamo lanciarlo sulla classe internal.dsl.SigningConfig.

per rendere il codice di lavoro, siamo in grado di creare sia internal.dsl.SigningConfig invece di DefaultSigningConfig:

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 

o avvolgere DefaultSigningConfig con il modello DSL interno:

android{ 
    signingConfigs { 
     debug { 
      initWith loadFromPropertiesFile("DEBUG_KEY_PROPERTIES") 
     } 
    } 

    buildTypes { 
    debug { 
     signingConfig signingConfigs.debug 
    } 
    } 
} 
Problemi correlati