最近要作一個 android 產品的變種版本,須要編出不一樣版本,每一個版本有不一樣的包名、圖標等等,和一些特有的邏輯。html
好久以前作過相似的工做,當時沒有 gradle, 用的方法是把公共代碼抽成一個 library,不一樣版本建一個工程引用公共 libery。可是這種方法每一個版本要建一個工程,工做量較大,而且會有一些重複代碼,很差維護。java
如今的工程是用 gradle 構建的,網上查了一下應該用 product flavors 作這個事情,以前沒接觸過,如今把方法記錄在這裏。android
Product flavors 用法很簡單。在 build.gradle 的 android 段中加入git
android { ... productFlavors { demo1 { applicationId "com.mycompany.demo1" } demo2 { applicationId "com.mycompany.demo2" } } }
gradle 的任務裏就會多了 assembleDemo1 和 assembleDemo2,能夠編出不一樣的版本。applicationId 是 apk 的包名,並且這個 applicationId 不會影響資源類 R 所在的包,在代碼裏不一樣版本引用的 class R 都是在 AndroidManifest.xml 所指定的 package 裏,因此很方便。github
Android Studio 界面左下角有個Build Variants 的選項,能夠選擇當前編那個版本。app
在 sourceSets段中能夠設置不一樣版本的代碼和資源位置。gradle
sourceSets { main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src/main/java'] resources.srcDirs = ['src/main/java'] aidl.srcDirs = ['src/main/java'] renderscript.srcDirs = ['src/main/java'] res.srcDirs = ['src/main/res'] assets.srcDirs = ['assets'] jniLibs.srcDirs = ['libs'] } demo1.java.srcDirs = ['src/demo1/java'] demo1.res.srcDirs = ['src/demo1/res'] demo2.java.srcDirs = ['src/demo2/java'] demo2.res.srcDirs = ['src/demo2/res'] }
這裏 main 是公共的代碼和資源,demo1 及 demo2 中找不到的文件會在 main 中查找,所以每一個版本下只要放本身改動過的文件就能夠了。ui
在 productFlavors 中,能夠指定配置google
productFlavors { demo1 { applicationId "com.mycompany.demo1" buildConfigField 'String', 'HOST', '"http://www.baidu.com"' } demo2 { applicationId "com.mycompany.demo2" buildConfigField 'String', 'HOST', '"http://www.google.com"' }
在代碼中能夠用 BuildConfig.HOST 來訪問不一樣的配置。code
若是不一樣版本權限不一樣,能夠用 manifestPlaceholders 修改 AndroidManifest.xml 中的內容來實現。
AndroidManifest.xml 中:
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="${billPermission}" />
對 billPermission 設置不一樣的值,能夠控制有沒有內購權限:
productFlavors { demo1 { applicationId "com.mycompany.demo1" manifestPlaceholders = [ "billPermission": "com.android.vending.BILLING", ] } demo2 { applicationId "com.mycompany.demo2" manifestPlaceholders = [ "billPermission": "android.permission.INTERNET", ] }
只有 demo1 有 com.android.vending.BILLING 權限。demo2 因爲 INTERNET 權限和前面重複,會被忽略掉
Product Flavor 還有許多能夠控制的地方,瞭解更多能夠訪問 Android Plugin DSL Referrence