Yapı Lezzetlerini Kullanma - Kaynak klasörleri yapılandırma ve build.gradle


166

Lütfen dikkat: Cevap Xavier'in Yanıtından sonra düzenlendi

Android Studio'da aynı Uygulama projesi için farklı Yapı Lezzetleri kullanmaya çalışıyorum . Ancak, uygun şekilde çalışacak şekilde yapılandırmak için korkunç bir zamanım var gibi görünüyor.

Adımlar:

  1. 'Test' adlı yeni bir Android Studio Projesi oluşturun.
  2. Build.gradle * dosyasını açın ve aşağıdaki satırları ekleyin:

    productFlavors {
    flavor1 {
        packageName 'com.android.studio.test.flavor1'
        }
    flavor2 {
        packageName 'com.android.studio.test.flavor2'
        }
    }
  3. Android Studio'yu yeniden başlattıktan sonra , Build Varyantları bölümünde 4 build varyantı görüyorum . Yani şimdiye kadar ürün lezzetlerini ayarlamakta başarılı olduk. **
  4. Flavor1 için yeni bir Kaynak klasör oluşturuldu ; ancak bunu doğru şekilde yaptığımdan emin değilim. İşte böyle yaptım:

    • Bu proje için Paket adımın: com.foo.test
    • srcKlasöre sağ tıklayın, flavor1 için, aslında yapıda olduğu gibi gezginde ayrı klasörleri oluşturdum src/flavor1/java/com/foo/test/MainActivity.java.
    • 'Java' klasörü mavi olduğundan , IDE'nin etkin bir kaynak dizini bildiği anlamına gelir. Ayrıca, paket otomatik olarak oluşturuldu. Buna rağmen, yinelenen sınıf için bir uyarı alıyorum. Buradaki ekran görüntüsüne bakın.
    • Flavor2 için, paketi manuel olarak oluşturmayı denedim, ancak flavor2 için 'src' klasörü mavi görünmüyor ve bu nedenle sağ tıklandığında seçenekler farklı ve benim için 'Yeni Paket' mevcut değil. Buradaki resme bakın.
    • Flavor1 için, maviye dönüşen bir 'res' dizini de oluşturduğumu, ancak buna rağmen, farklı kullanmak istersem, bir Android Kaynak dosyası veya Andorid kaynak dizini oluşturma olanağı sunmadığını unutmayın. Farklı tatlar için kaynaklar.

Yanlış bir şey mi yapıyorum? Yoksa bir şey mi kaçırıyorum? Daha fazla bilgiye ihtiyacınız varsa bana bildirin.

* Projemde iki build.gradle dosyası var gibi görünüyor . Biri proje klasörünün kökünde (\ GradleTest) bulunur, bu boştur. İkincisi \ GradleTest alt klasörünün kökünde bulunan ve ayrıca 'GradleTest' (GradleTest-GradleTest) olarak etiketlenmiş, açıldığında zaten kodu olan; bu yüzden düzenlediğim bu.

** Ben gradle ayarları kontrol ve görünüşe Kullanım oto-ithalat yapıldı zaten etkin. Buna rağmen build.gradle dosyasında değişiklik yapmak derleme değişkenlerini otomatik olarak güncellemez . Not: Ayrıca Build - Rebuild Project ve / veya Build - Make Project, no-go kullanmayı denedim. Yine de projeyi kapatmam ve değişikliklerin yürürlüğe girmesi için yeniden açmam gerekiyor.


applicationIdBunun yerine artık desteklendiğini unutmayın packageName.
Hamzeh Soboh

Yanıtlar:


220

Studio tercihlerine girdiyseniz Gradle bölümünün altında projeniz için otomatik içe aktarmayı etkinleştirebilirsiniz (bunu daha sonra varsayılan olarak etkinleştireceğiz). Bu, Studio'nun build.gradle dosyasını her düzenlediğinizde yeniden içe aktarmasını sağlar.

Tatlar oluşturmak, onlar için özel kod kullanacağınız anlamına gelmez, bu nedenle klasörleri oluşturmayız. Bunları kendiniz oluşturmanız gerekir.

Benim ES konuşmamıza bakarsanız , çeşidi oluşturmak için lezzetlerden ve yapı türünden değerleri nasıl karıştırdığımızı göreceksiniz.

Java kaynağı için:

src/main/java
src/flavor1/java
src/debug/java

hepsi tek bir çıktı oluşturmak için kullanılır. Bu, aynı sınıfı tanımlayamadıkları anlamına gelir.

İki lezzette aynı sınıfın farklı bir versiyonuna sahip olmak istiyorsanız, her iki lezzette de oluşturmanız gerekir.

src/flavor1/java/com/foo/A.java
src/flavor2/java/com/foo/A.java

Ve sonra src / main / java kodunuzu yapabilirsiniz

import com.foo.A

seçilen aromaya bağlı olarak, doğru com.foo.A sürümü kullanılır.

Bu aynı zamanda A'nın her iki sürümünün de aynı API'ye sahip olması gerektiği anlamına gelir (en azından src / main / java / ... içindeki sınıflar tarafından kullanılan API söz konusu olduğunda ...

Düzeltilmiş soruyla eşleşecek şekilde düzenleyin

Ayrıca, aynı A sınıfını yalnızca birbirini dışlayan kaynak klasörlere koymak önemlidir. Bu durumda src / flavor1 / java ve src / flavor2 / java asla birlikte seçilmez, ancak ana ve lezzet1 seçilir.

Bir aktivitenin farklı lezzette farklı bir versiyonunu sunmak istiyorsanız, src / main / java içine koymayın.

3 lezzetiniz varsa ve yalnızca flavor1 için özel bir tane istiyorsanız, flavor2 ve flavor3 aynı aktiviteyi paylaşırsa, bu diğer iki aktivite için ortak bir kaynak klasör oluşturabileceğinizi unutmayın. Yeni kaynak klasörler oluşturma ve kaynak kümesini bunları kullanacak şekilde yapılandırma konusunda tam esnekliğe sahipsiniz.

Diğer noktalarınızda:

2. lezzet kaynak klasörünün mavi olmaması normaldir. Etkinleştirmek için 2. tada geçmeniz gerekir ve daha sonra içeride paketler ve sınıflar oluşturabilirsiniz. O zamana kadar Studio bunu bir kaynak klasör olarak görmüyor. İleride IDE'yi bu etkin olmayan kaynak klasörlerden haberdar etmek için bunu geliştireceğiz .

Res klasöründe kaynak dosyaları oluşturamamanın da normal olduğunu düşünüyorum. Menü sistemi, tüm bu ekstra kaynak klasörleriyle başa çıkmak için güncellenmemiştir. Bu daha sonra gelecek.


1
Cevabımın sonuna bazı yeni unsurlar ekledim, ancak yinelenen mantıklı. Her ikisi de flavor1 seçerken kullanılan src / main / java ve src / flavor1 / java sınıflarında aynı sınıfa sahip olamazsınız. Cevabımda, aynı sınıfı sadece flavor1 / java ve flavor2 / java'ya nasıl koyduğuma dikkat edin, çünkü bunlar özeldir ve asla birlikte etkinleştirilmez.
Xavier Ducrohet

Hey Xavier, bana bir etkinliğin farklı bir versiyonunu tatlarımda nasıl kullanabileceğime dair daha ayrıntılı bir açıklama verebilir misiniz? MainActivity'nin farklı sürümlerini kullanmak istediğim bir test projem var, ancak her iki uygulamada da (flavor1 ve flavor2) sadece main / java sürümü var. MainActivity'yi main / java içine yerleştirmediğimde, uygulama başlattığımda kilitleniyor.
JensJensen

@XavierDucrohet, farklı kaynakların yanı sıra lezzetleri temel alan farklı kodlara sahip olmaya ne dersiniz, ancak aynı modülde kod ve kaynakları karıştırmak zorunda kalmadan lezzete dayalı bir modül veya diğerini dahil edebilmemiz için farklı modüllere sahip olmaları? Bu destekleniyor mu?
Valerio Santinelli

3
@ValerioSantinelli Lezzet başına bağımlılıklar yapabilirsiniz. KullanımflavorCompile ...
Xavier Ducrohet

@XavierDucrohet Önerdiklerinizi denedim ama beklediğim gibi çalışmıyor.
Projemin

19

Android'de "Ürün Lezzetleri"

Bazen aynı uygulamanın farklı sürümleri ile ilgili olarak farklı ana makineler, simgeler ve hatta paket adları ile nasıl çalışılacağı sorulur.

Bunu yapmanın birçok nedeni ve gitmenin kolay bir yolu var: Ürün Aromaları.

Build.gradle betiğinizde daha önce tanımladığım bu tür şeyleri tanımlayabilirsiniz.

Ürün aromaları Bu makalenin bir kısmı ürün aromaları üzerine düşünülerek yazılmıştır, peki bunlar nedir? Android belgelerine ilişkin olarak:

Ürün aroması, proje tarafından oluşturulan uygulama sürümünün özelleştirilmiş bir sürümünü tanımlar. Tek bir proje, üretilen uygulamayı değiştiren farklı tatlara sahip olabilir.

Onları nasıl tanımlayabilirsiniz? Build.gradle üzerine hangi tatları tanımlamak istediğini yazmalısın:

productFlavors {  
        ...
        devel {
            ...
        }

        prod {
            ...
        }
    }

Şimdi, bizim app iki farklı tatlar olacak. Android Studio'da Yapı Varyantları sekmesinde de kontrol edebilirsiniz.

Yapı varyantları

Birden fazla paket adı

Telefonunuza geliştirme durumu olan bir uygulama ve üretim durumu için bir uygulama yüklemek isterseniz ne olur? Bildiğiniz gibi, yalnızca aynı paket adına sahip bir uygulama yükleyebilirsiniz (telefonunuzda yüklü olanla aynı yeni bir APK yüklemeye çalışırsanız, güncellemeye çalışacaktır).

Yapmanız gereken tek şey, ürün lezzetlerinizin her birinde tanımlamaktır:

android {  
    productFlavors {
        devel {
            applicationId "zuul.com.android.devel"
        }
        prod {
            applicationId "zuul.com.android"
        }
    }
}

Lezzete bağlı olarak birden fazla ana bilgisayara istek gönderme Daha önce olduğu gibi, ürün lezzet yapılandırma alanınıza bazı parametreler eklemelisiniz.

android {  
    productFlavors {
        devel {
            applicationId "zuul.com.android.devel"
            buildConfigField 'String', 'HOST', '"http://192.168.1.34:3000"'

        }

        prod {
            applicationId "zuul.com.android"
               buildConfigField 'String', 'HOST', '"http://api.zuul.com"'

        }
    }
}

Örnek olarak, hangi sunucuyu işaret ettiğinize ve aromaya bağlı olmadan uygun sunucuya istek göndermek için bunu Retrofit ile nasıl entegre edebileceğinizi göstermeye çalışacağız. Bu durumda bu Zuul android uygulamasının bir alıntısıdır:

public class RetrofitModule {

    public ZuulService getRestAdapter() {
        RestAdapter restAdapter = new RestAdapter.Builder()
                .setEndpoint(BuildConfig.HOST)
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .build();
        return restAdapter.create(ZuulService.class);
    }

}

Gördüğünüz gibi, tanımladığınız değişkene erişmek için BuildConfigclass'ı kullanmanız yeterlidir.

Kodunuz aracılığıyla kullanılabilen herhangi bir değişken HOST değişkeni, kodunuzda gösterebileceğiniz tek değişken değildir. Ne istersen yapabilirsin:

prod {  
    applicationId "zuul.com.android"
    buildConfigField 'String', 'HOST', '"http://api.zuul.com"'
    buildConfigField 'String', 'FLAVOR', '"prod"'
    buildConfigField "boolean", "REPORT_CRASHES", "true"
}

Bunlara aşağıdaki gibi erişebilirsiniz:

BuildConfig.HOST  
BuildConfig.FLAVOR  
BuildConfig.REPORT_CRASHES  

Lezzet başına farklı simgeler Lezzet başına farklı simgeler kullanmak istiyorsanız, hangisini açtığınızı görsel olarak tespit edebilirsiniz (bunu adıyla da yapabilirsiniz ... Ama alana sığamaz!) lezzetlerin her biri için yeni dizin yapıları tanımlamak.

Az önce kullandığım örnekte iki lezzet var: devel ve prod. Ardından, istediğimiz kaynakları tanımlayabilmemiz için iki yeni dizin yapısı tanımlayabiliriz:

yapı

Bu strings.xml, integers.xml, arrays.xml, vb. Gibi diğer kaynaklarla çalışır .

İmzalama Ayarlarını Yapılandırma

Gradle derleme yapılandırmalarını kullanarak sürüm derleme türünüz için imzalama yapılandırmalarını el ile yapılandırmak için:

1. bir anahtar deposu oluşturun. Anahtar deposu, bir dizi özel anahtar içeren bir ikili dosyadır. Anahtar deponuzu güvenli bir yerde saklamalısınız. 2.Özel bir anahtar oluşturun. Özel anahtar, bir kişi veya şirket gibi uygulamayla tanımlanacak olan varlığı temsil eder. İmza yapılandırmasını modül düzeyindeki build.gradle dosyasına ekleyin:

android {
...
defaultConfig {...}
signingConfigs {
    release {
        storeFile file("myreleasekey.keystore")
        storePassword "password"
        keyAlias "MyReleaseKey"
        keyPassword "password"
    }
}
buildTypes {
    release {
        ...
        signingConfig signingConfigs.release
    }
}

}

İmzalı bir APK oluşturun:

İmzalı bir APK oluşturmak için ana menüden Oluştur> İmzalı APK Oluştur'u seçin. App / build / apk / app-release.apk içindeki paket artık sürüm anahtarınızla imzalandı.

ref: https://developer.android.com/studio/build/build-variants.html#signing,http://blog.brainattica.com/how-to-work-with-flavours-on-android/



7

Yeni lezzetler ekledikten sonra projenizi yeniden yüklemeniz gerekiyor gibi görünüyor build.gradle. Bundan sonra, Yapı Varyantları görünümünde 4 yapı Varyantı görürsünüz (pencerenin sol kenarından erişirsiniz).

Ek kaynak dizinlerle ilgili olarak, bunları elle oluşturmanız gerekir gibi görünüyor: src/flavor1/javave src/flavor2/java. Sen "Yapı Varyantlar" görünümünde lezzet değişen değişeceğini göreceksiniz anda etkin kaynak dizinleri (bir zaman dizini mavidir aktif kaynak dizin )

Son olarak, "gradle yeni lezzetleriniz için yeni sourceSets oluşturur", gradle'ın nesneleri oluşturacağı android.sourceSets.flavor1ve android.sourceSets.flavor2bunları build.gradle komut dosyasında kullanabileceğiniz anlamına gelir . Ancak bu nesneleri bunları görmüyorum, bu yüzden dinamik olarak oluşturulur build.gradle(Bunu okumanızı öneririz: http://www.gradle.org/docs/current/userguide/tutorial_using_tasks.html Özellikle 6.6: açıklamak dinamik görev oluşturma Gradle komut dosyası harika bir komut dosyasıdır, bu yüzden harikalara aşina olmanızı öneririm)


2
İthalat notunun Build VariantsGörünüm olduğunu düşünüyorum, bunu fark etmedim.
Chris.Jenkins

2

Projemi Gradle'a geçirdiğimde de aynı sorunu yaşadım. Sorun, derlemenin uygun kaynaklar klasörünü bulamamasıydı. Bunu build.gradle'daki android öğesinin altına ekleyerek düzelttim:

sourceSets {
        main {
            res.srcDirs = ['myProject/res']
        }
    }

0

Önemli ve beni bir süre engelleyen bir şey, gradle'daki lezzet tanımının içinde tanımlanan pakete karşılık olarak paketle eşleşmesi gereken lezzet adının olmasıdır. Örneğin:

src/flavor1/java/com/foo/A.java

eşleşecek

productFlavors {
  flavor1 {
    packageName 'com.android.studio.test.foobar'
  }
}

fakat

src/foobar/java/com/foo/A.java lezzet1 yapısı için kullanılmayacaktır.


0

Derecede:

Derleme Türleri için yalnızca aşağıdakilere ihtiyacınız vardır:

buildTypes {
   release{
    //proguard, signing etc.
   }
   debug {
    //development
   }
  }
}

Ve sonra lezzetler için ihtiyacınız olanları eklersiniz

productFlavors {
    pro {
        applicationIdSuffix '.paid'
        buildConfigField 'boolean', 'PRO', 'true'
    }
    free {
        applicationIdSuffix '.free'
        buildConfigField 'boolean', 'PRO', 'false'
    }
}
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.