Android編譯變體配置簡介-構建不同版本類型(buildTypes)和多渠道打包(productFlavors)

一、概述

在Android開發中,我們需要構建不同的版本類型(Relase、Debug、Alpha),或者是不同渠道(豌豆莢、小米、三星等),這些都可以配置編譯變體來實現,本文就是希望通過簡短且概括性的文字來進行解釋。

以下內容均可在Google官方文檔中找到,詳看:配置編譯變體

二、使用buildTypes構建不同版本類型

什麼叫不同版本類型?根據我的理解就是,Google提供了一系列屬性(參考:版本類型 DSL參考),然後我們可以根據需要爲不同版本配置不同的屬性,從而實現打出來差異化的包。

如果你沒接觸過,你應該會覺得很抽象,舉個例子:

比如說,我要給當前項目構建兩種包(Debug和Release),Debug版本可以支持adb debug,Release版本則不行,同時Debug版本的包名後綴需要在原有基礎上增加“.debug”,那麼我們就可以通過配置buildTypes來實現,代碼如下:

1.修改app目錄下的build.gradle文件

⚠️注意:release版本里面一定要加上簽名,不然打出來的包安裝不了,會提示沒有簽名信息!!簽名過程這裏不贅述了,不懂的同學也是自行搜索。

android {
    //...
    
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            // release版本簽名
            signingConfig signingConfigs.release
        }

        debug {
            applicationIdSuffix ".debug"
            debuggable true
        }
    }
    
    //...
}

2.同步代碼

一般修改build.gradle後,都會要求你Sync Now,不懂怎麼同步代碼的同學自行搜索。

3.編包

在Teminal執行命令gradlew assemble,編譯成功會提示如下:

image

然後打開你的目錄app下的build/apk/目錄,下面多了兩個文件夾,分別是debug和release,裏面分別有兩個apk,如下圖所示。

image

4.驗證

分別安裝兩個app,我們就可以驗證它們是否滿足我們的要求。

首先安裝debug目錄下的apk,打開調試工具可以看到,包名確實變成了“.debug”結尾,並且是可以調試的。

image

再來看relase包,安裝後在調試工具看不到對應的可調試app,因爲我們沒有設置它是debuggable,通過pm list packages命令查看已安裝app,確實有一個com.ryan.testbuildtype的app,跟debug包的包名是不一樣的。

image

由此驗證得知,確實可以通過buildTypes來構建不同類型的包,當然,在版本類型 DSL參考裏面提供了很多不同的屬性,如是否可以調試JNI代碼的屬性jniDebuggable、是否打開Proguard的屬性useProguard、是否壓縮資源文件的屬性shrinkResources等,你都可以根據自己的需求來進行構建不同屬性類型的包。

三、使用productFlavors實現多渠道打包

在Google官方的解釋是productFlavors是用以構建不同產品特性使用的,但是國內的開發者都喜歡用以實現多渠道打包,所以本文暫且這麼來寫。

我們都知道通過buildTypes可以實現構建不同屬性的包,但是針對不同類型維度的打包,確實有心無力,怎麼說?

比如,我們需要構建不同區域的包,實現內容是一樣的,但是所有網絡請求的域名隨區域的變化而變化,假如我們在代碼中通過if-else來實現,會顯得非常冗餘,下面就以這個例子來講解productFlavors的使用。

1.首先在app目錄下的build.gradle文件增加productFlavors屬性

首先需要定義一個flavorDimensions,例如我定義的是location作爲區分維度。假如你有多個維度,那麼最終就會構建出來幾個維度多種組合的包。

android {
    // ...
     // 特性維度
    flavorDimensions "location"
    productFlavors {
        guangzhou{
            dimension "location"
        }

        chengdu {
            dimension "location"
        }
    }
    // ...
}

2.同步代碼

3.在src目錄創建對應flavor的目錄

如我們要根據地區,構建不同的ip地址,那麼我們就可以把ip定義到java文件裏面,在app目錄下的src目錄,右鍵new->Folder->Java Folder,然後選擇對應的flavors,如本例中的guangzhou,就會生成一個guangzhou的目錄,然後在java目錄下新建一個包名(這個是必須要的),然後創建一個文件,如下圖所示:

image

然後在裏面定義廣州的域名:

public class MyConstants {
    public static final String DOMAIN = "http://www.guangzhou.com";
}

同樣地,創建成都的目錄,並創建同樣的包名和類名,並創建同樣的變量:

public class MyConstants {
    public static final String DOMAIN = "http://www.chengdu.com";
}

也許你的java文件變成了紅色,如下圖所示:

image

不用擔心,只是你當前的flavor是廣州而已,選擇as左下角的Build Variants,切換到成都的flavor,你的文件就是正常的類了。

image

4.在main目錄下的文件引用不同flavor的屬性

爲了測試方便,我們就在MainActivity中打印MyConstants的值即可,代碼如下所示:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        TextView textView = findViewById(R.id.tv_text);
        textView.setText(MyConstants.DOMAIN);
    }
}

使用teminal打包,構建出兩個flavor的debug包:

image

分別安裝,可以看到最終打印的域名是不一樣的,從而實現了不同渠道打包:

image

image

當然,這只是非常簡單的應用,當你需要進行更大代碼差異化的時候,也可以利用productFlavors來劃分特性,從而可以同時構建出不同渠道的apk,避免在代碼中進行冗雜的if-else判斷。

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