Android Gradle'daki çoklu lezzet kitaplığına dayalı çoklu lezzet uygulaması


102

Uygulamamın çeşitli pazarlar için uygulama içi faturalandırma sistemleri için birkaç çeşidi var.

Tüm projelerim için temel kodu paylaşan tek bir kitaplığım var. Ben de bu ödeme sistemlerini ürün çeşidi olarak bu kitaplığa eklemeye karar verdim.

Soru, android kitaplığında ürün aromaları olabilir mi?

Öyleyse, uygulamanın ilgili aromasına nasıl farklı tatlar ekleyebilirim?

Çok araştırdım ve bu senaryo hakkında hiçbir şey bulamadım. Bulduğum tek yakın şey, http://tools.android.com/tech-docs/new-build-system/user-guide'de şuydu :

dependencies {
    flavor1Compile project(path: ':lib1', configuration: 'flavor1Release')
    flavor2Compile project(path: ':lib1', configuration: 'flavor2Release')
}

Yapılandırmayı farklı şeylerle değiştirdim ama işe yaramadı!

Android studio 0.8.2 kullanıyorum.


Birçok aramadan sonra, bunu başarmanın bir yolunu bulamadım, Android eklentisini en son 3.4.2sürüme yükselttim ve en son sürüme geçsem bile, 5.5.1derleme zamanıyla başarısız oldu veya kaynak bağlama aapt'ta başarısız oldu veya kitaplığın içindeki sembolü bulamıyorum modül
VinceStyling

Yanıtlar:


141

Sonunda bunu nasıl yapacağımı öğrendim, aynı problemle karşılaşan diğerlerine burada açıklayacağım:

Anahtar kısım, library build.gradle içinde publishNonDefault'u true olarak ayarlamaktır. Ardından, bağımlılıkları kullanım kılavuzunda önerildiği gibi tanımlamalısınız.

Bütün proje şöyle olacak:

Kitaplık build.gradle:

apply plugin: 'com.android.library'

android {        
    ....
    publishNonDefault true
    productFlavors {
        market1 {}
        market2 {}
    }
}

proje build.gradle:

apply plugin: 'com.android.application'

android {
    ....
    productFlavors {
        market1 {}
        market2 {}
    }
}

dependencies {
    ....
    market1Compile project(path: ':lib', configuration: 'market1Release')
    market2Compile project(path: ':lib', configuration: 'market2Release')
}

Artık uygulama çeşidini ve Yapı Varyantları panelini seçebilirsiniz ve kitaplık buna göre seçilecek ve tüm derleme ve çalıştırma seçilen aroma göre yapılacaktır.

Kitaplığa dayalı birden fazla uygulama modülünüz varsa Android Studio, Varyant seçim çakışmasından şikayet eder, Tamam, sadece görmezden gelin.

görüntü açıklamasını buraya girin


Paylaştığınız için teşekkürler, artık defaultPublishConfig geçici çözümümden kurtulabilirim.
Delblanco

2
AS 1.1.0'ı çalıştırdığınızda, yukarıdaki çözüm hala çalışıyor gibi görünüyor, ancak 1) hata ayıklama / sürüm oluşturma seçeneği kayboldu ve kitaplıkta bulunan ve uygun kodu çok sık üretemeyen AIDL ile ilgili sorunlar yaşamaya devam ediyorum. Bununla ilgili herhangi bir fikrin var mı?
3c71

1
@IgorGanapolsky buildTypes'in bununla ilgisi yok. Her çeşidin tüm yapı türleri vardır (genellikle hata ayıklama ve yayınlama) ve hepsi bu yaklaşımla çalışır.
Ali

1
@ An-droid market1 aroması için kullanılacak kütüphaneyi tanımlar!
Ali

1
Neden derleme türü "sürüm" olarak ayarlandı? Hata ayıklama yapıları sırasında "yayın" yapı türü seçildi mi?
WindRider

35

Ali'nin cevabında bir sorun var . Yapı çeşitlerimizde çok önemli bir boyutu kaybediyoruz. Biz (4 (2 x 2) altına bizim örneğimizde) tüm seçenekleri sahip olmak istiyorsanız sadece eklemek zorunda özel yapılandırmalar içinde ana modül build.gradle tüm çoklu lezzet çoklu buildType kullanabilmek için için dosyanın Build Variants. Ayrıca belirlemek zorunda publishNonDefault gerçek de kütüphane modülü build.gradle dosyası.

Örnek çözüm:

Lib build.gradle

android {

    publishNonDefault true

    buildTypes {
        release {
        }
        debug {
        }
    }
    productFlavors {
        free {
        }
        paid {
        }
    }
}

Uygulama build.gradle

android {

    buildTypes {
        debug {
        }
        release {
        }
    }
    productFlavors {
        free {
        }
        paid {
        }
    }
}

configurations {
    freeDebugCompile
    paidDebugCompile
    freeReleaseCompile
    paidReleaseCompile
}

dependencies {

    freeDebugCompile project(path: ':lib', configuration: 'freeDebug')
    paidDebugCompile project(path: ':lib', configuration: 'paidDebug')
    freeReleaseCompile project(path: ':lib', configuration: 'freeRelease')
    paidReleaseCompile project(path: ':lib', configuration: 'paidRelease')

}

Error:java.lang.RuntimeException: Error: more than one library with package nameBaşvurumda aynı şeyleri yaptıktan sonra , oluştu
Chetan Joshi

22

Android Eklentisi 3.0.0 ve üzeri için güncelleme

Resmi Android Dokümantasyonuna göre - Yerel modüller için bağımlılık yapılandırmalarını taşıyın ,

Varyant-bilinçli bağımlılık çözümlemesiyle, artık yerel modül bağımlılıkları için freeDebugImplementation gibi varyanta özgü konfigürasyonları kullanmanıza gerek yoktur - eklenti bunu sizin için halleder

Bunun yerine bağımlılıklarınızı aşağıdaki gibi yapılandırmalısınız:

dependencies {
    // This is the old method and no longer works for local
    // library modules:
    // debugImplementation project(path: ':library', configuration: 'debug')
    // releaseImplementation project(path: ':library', configuration: 'release')

    // Instead, simply use the following to take advantage of
    // variant-aware dependency resolution. You can learn more about
    // the 'implementation' configuration in the section about
    // new dependency configurations.
    implementation project(':library')

    // You can, however, keep using variant-specific configurations when
    // targeting external dependencies. The following line adds 'app-magic'
    // as a dependency to only the "debug" version of your module.

    debugImplementation 'com.example.android:app-magic:12.3'
}

Yani Ali'nin cevabında, değiş

dependencies {
    ....
    market1Compile project(path: ':lib', configuration: 'market1Release')
    market2Compile project(path: ':lib', configuration: 'market2Release')
}

-e

implementation project(':lib')

Ve eklenti, varyanta özgü yapılandırmaları otomatik olarak halleder. Umarım Android Studio Eklentisini 3.0.0 ve üstüne yükseltmek isteyenlere yardımcı olur.


7

Android Eklentim 3.4.0 ve şimdi yapılandırmalara ihtiyaç duymadığını görüyorum.İhtiyacınız olan tek şey, uygulamadaki lezzet Boyutları ve ürün Aromalarının aynı aromaya sahip bir ürünFlavoru ve kitaplıklardaki ürün Aromaları içerdiğinden emin olmaktır.Örnek için:

Mylibrary'de build.gradle

apply plugin: 'com.android.library'

android {        
    ....
    flavorDimensions "mylibFlavor"

    productFlavors {
        market1
        market2
    }
}

uygulamanın build.gradle'ı:

apply plugin: 'com.android.application'

android {
    ....
    flavorDimensions "mylibFlavor", "appFlavor"
    productFlavors {
        market1 {
            dimension "mylibFlavor"
        }
        market2 {
            dimension "mylibFlavor"
        }
        common1 {
            dimension "appFlavor"
        }
        common2 {
            dimension "appFlavor"
        }
    }
}

dependencies {
    ....
    implementation project(path: ':mylibrary')
}

Senkronizasyondan sonra, Varyant Oluşturma Penceresindeki tüm seçenekleri değiştirebilirsiniz: görüntü açıklamasını buraya girin


Peki ya ana uygulama modülümde aynı tatlara sahip olmak istemiyorsam? Kendi özel aromalarına sahip birden fazla uygulama modülüm ve kendi aromalarına sahip ortak bir modülüm olduğunu ve uygulamamda kütüphanemi belirli bir tada sahip kullanmak istediğimi varsayalım. Bunu nasıl yaptın? Kitaplık türlerimi tüm uygulamalara kopyalamak mantıklı değil.
Billda

@ Billda Hepsini kopyalamaya ihtiyacınız yok, sadece aynı productFlavor'u uygulamada tutun, örneğim için market1 veya market2'yi uygulamanın build.gradle'ında tutabilirim.
JiajiaGu

2

Bir AAR kitaplığında çalışan tatları elde etmek için, Android Kitaplığı modülünüzün build.gradle dosyasında defaultPublishConfig tanımlamanız gerekir.

Daha fazla bilgi için bkz: Kütüphane Yayını .

Kütüphane Yayını

Varsayılan olarak bir kitaplık yalnızca yayın varyantını yayınlar. Bu varyant, hangi varyantı kendileri inşa ederlerse etsinler, kütüphaneye referans veren tüm projeler tarafından kullanılacaktır. Bu, kaldırmaya çalıştığımız Gradle sınırlamaları nedeniyle geçici bir sınırlamadır. Hangi varyantın yayınlanacağını kontrol edebilirsiniz:

android {defaultPublishConfig "debug"}

Bu yayınlama yapılandırması adının tam varyant adına başvurduğunu unutmayın. Serbest bırakma ve hata ayıklama yalnızca tat olmadığında uygulanabilir. Aromaları kullanırken varsayılan yayınlanan varyantı değiştirmek isterseniz, şunu yazarsınız:

android {defaultPublishConfig "flavour1Debug"}


1

Şu anda bu mümkün değil, ancak doğru hatırlıyorsam eklemek istedikleri bir özellik. (Düzenleme 2: bağlantı , link2 )

Düzenleme: Şu an defaultPublishConfigiçin hangi kitaplık varyantının yayınlanacağını bildirme seçeneğini kullanıyorum :

android {
    defaultPublishConfig fullRelease
    defaultPublishConfig demoRelease 
}

1
Yani, uygulamayı her derleyeceğimde, bunu kütüphanenin build.gradle'ında değiştirmem gerekiyor?
Ali

Pekala, evet ... her seferinde uygulamayı farklı bir tat ile derlemek istediğinizde.
Delblanco

Aslında kitaplık modülü için tatlar tanımladığımda, miras alınan R paketi uygulama modülünde bulunamıyor.
Ali

Gradle dosyalarını AS'de senkronize ettiniz mi?
Delblanco

@Delblanco Bu el emeği gibi görünüyor ve çok kırılgan (geliştiriciler tembeldir ve build.gradle dosyalarını değiştirmeyi unuturlar).
IgorGanapolsky

1

Bu konunun kapatıldığını biliyorum, ancak yalnızca gradle 3.0 ile bir güncelleme, şuna bakın: https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html#variant_aware ve grep matchingFallbacksvemissingDimensionStrategy . Artık modül çeşitleri arasındaki bağımlılıkları bildirmek çok daha kolay.

... ve gradle3.0 ile bu kesin durumda, tatlar aynı adı paylaştığından, gradle onları sihirli bir şekilde haritalayacaktır, konfigürasyona gerek yoktur.


Benim için çalışma zamanında üretilen şeyler atlanmış gibi görünüyor. Örnek olarak simonvt-> schematics generation artık benim için yeni yöntemle çalışmıyor. : - /
Stefan Sprenger

1

Ayrıca çeşitli seçenekler için modülleri derlerken bir sorunla karşılaştım.

Ne buldum:

Gradle 3.0.1'den beri publishNonDefault truelib build.gradledosyasına eklemeye ihtiyacımız yok gibi görünüyor .

Bir sınıfı derledikten sonra şunu BaseExtensionbuldum:

public void setPublishNonDefault(boolean publishNonDefault) {
   this.logger.warn("publishNonDefault is deprecated and has no effect anymore. All variants are now published.");
}

Ve bunun yerine:

dependencies {
...
   Compile project(path: ':lib', configuration: 'config1Debug')
}

Kullanmalıyız:

dependencies {
...
   implementation project(':lib')
}

Yalnızca önemli olan, bir configurations {...}parça eklemektir .build.gradle .

Bu nedenle, uygulama build.gradledosyasının son çeşidi :

buildTypes {
   debug {
      ...
   }

   release {
      ...
   }
}

flavorDimensions "productType", "serverType"
productFlavors {
   Free {
      dimension "productType"
      ...
   }
   Paid {
      dimension "productType"
      ...
   }
   Test {
      dimension "serverType"
      ...
   }
   Prod {
      dimension "serverType"
      ...
   }
}

configurations {
   FreeTestDebug
   FreeTestRelease
   FreeProdDebug
   FreeProdRelease
   PaidTestDebug
   PaidTestRelease
   PaidProdDebug
   PaidProdRelease
}

dependencies {
   implementation fileTree(dir: 'libs', include: ['*.jar'])
   implementation project(':lib')
   ...
}

Ayrıca, Filtre çeşitlerini de kullanabilirsiniz. derleme varyantlarını kısıtlamak için .

Ps, settings.gradledosyaya aşağıdaki gibi modülleri eklemeyi unutmayın :

include ':app'
include ':lib'
project(':lib').projectDir = new File('app/libs/lib')

efendim, komut dosyasının hava durumunu kitaplığı belirli bir konfigürasyona dahil edip etmeyeceğini nasıl belirleyeceğini açıklayabilir misiniz? Demek istediğim, belirli bir lezzet için biraz lib kullanmam gerektiğinde bir
durumum var

Böyle bir duruma girmedi. Ancak bir google tutorial developer.android.com/studio/build/dependencies , "bağımlılıklar {...}" bloğundaki "uygulama" komutundan önce bir önek eklemenizi önerir. Yani bağımlılıklar {ücretliImplementation projesi (': lib')} veya bağımlılıklar {debugImplementation project (': lib')} veya herhangi bir çoklu varyant kombinasyon bağımlılıkları {ücretliProdDebugImplementation projesi (': lib')}. Bir göz atın ve bize geri bildirimde
Sergio
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.