最近要作一个 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