Android-使用productFlavors配置項目移植

原創-轉載請註明出處

概述

有時候需要做兩個或多個項目,但都用的同一套代碼.只有稍微的一些佈局或者代碼的改動.
我們常規的做法是再切一個分支,再在這個分支上做相應的改動.但比如發現了某一處bug,或者需要統一改個需求.那我們就需要在每一個分支上都進行這種變動.
如果項目多的話會很不好維護.下面就介紹怎樣通過productFlavors的方式配置項目移植.

Flavor

在主項目build.gradle中配置productFlavors

android{
    ...
    defaultConfig{
    ...
    }
    productFlavors{
        jkxt {
            applicationId "com.****.****"
            buildConfigField "String", "PROJECT_SIGN", "\"jkxt\""
            manifestPlaceholders = [BAIDU_CHANNEL_VALUE       : "*****",
                                    PACKAGE_NAME              : "*****"]
        }
        jkhd {
            applicationId "com.****.****"
            buildConfigField "String", "PROJECT_SIGN", "\"jkhd\""
            manifestPlaceholders = [BAIDU_CHANNEL_VALUE       : "*****",
                                    PACKAGE_NAME              : "*****"]
        }
    }
}

上面定義了一個productFlavors,gradle會爲這個flavor關聯對應的sourceSet,默認位置爲src/<flavorName>目錄,對應到本例就是src/jkhd,如果沒有建文件夾,則默認爲src/main.看如下解釋

The product flavors support the same properties as defaultConfig—this is because defaultConfig actually belongs to the ProductFlavor class. This means you can provide the base configuration for all flavors in the defaultConfig {} block, and each flavor can override any of these default values, such as the applicationId.

也就是說,defaultConfig中可以配置的屬性,比如applicationId,minSdkVersion等,都可以在productFlavors中配置,因爲defaultConfig就是一個productFlavor實例.

在本例中,解釋上面兩個屬性,buildConfigField可以理解爲定義一個常量,傳入的值分別代表type,name,value;
通過BuildConfig.PROJECT_SIGN 可以拿到相應的值,比如我們熟悉的BuildConfig.DEBUG,就是系統定義的一個常量.

manifestPlaceholders作用是動態替換manifest文件,傳入的是一個map對象,寫法如上所示.在配置多個項目時,一些第三方的key比如友盟,極光等需要進行動態配置,就需要用到這個屬性,在manifest文件中把需要動態配置的屬性按如下寫法,android:name="${PACKAGE_NAME}"

替換資源文件

上面講到productFlavors已經爲我們關聯了對應的sourceSet,所以我們只需要把不同的資源文件放入相應目錄下
以jkhd爲例,在src/jkhd目錄下新建res文件,新建需要替換的資源文件夾,比如需要替換app_name
只需要在src/jkhd/res/values/string.xml,新建app_name標籤即可.其他公用的資源不需要添加,找不到的話會默認從主項目下面找.

使用第三方sdk

做某些項目可能用用到不用的第三方sdk,但其他項目並不需要這個sdk,那麼怎麼爲特定的項目添加sdk呢?

android {
productFlavors {
    jkhd {
        }
    }
}
...
dependencies {
    jkhdCompile 'com.nineoldandroids:library:2.4.0'
}

然後通過反射的方法,進行具體判斷

class MyActivity extends Activity {
private boolean useSdk;

@override
public void onCreate(Bundle savedInstanceState) {
    try {
        Class.forName("com.nineoldandroids.......");
        useSdk = true;
    } catch (ClassNotFoundException ignored) {
        }
    }
}

動態替換代碼

  1. 如果在src/jkhd目錄下新建同名類的話會報類重複的問題.但我們可以新建src/jkhd,和src/jkxt兩個文件夾,在這兩個文件夾中同時寫入一個與主目錄不同的類,在主目錄中進行調用,這樣是沒有問題的
  2. 直接在主目錄中以判斷標記位的方法來達到動態替換的效果.

總結

productFlavors對於配置項目移植,和多渠道打包都非常方便,節省了我們大量的工作.目前所介紹的配置基本上可以滿足我們的需求.以後再也不用擔心多渠道打包和項目移植啦~

歡迎大家提出更多新的用法!

參考資料
Product-flavors
美團Android自動化之旅—適配渠道包

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章