使用 gradle 編譯多版本 android 應用

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

相關文章
相關標籤/搜索