1. 程式人生 > >Bugly多渠道熱更新解決方案

Bugly多渠道熱更新解決方案

Gradle使用productFlavors打渠道包的痛

有很多同學可能會採用配置productFlavors來打渠道包,主要是它是原生支援,方便開發者輸出不同定製版本的apk,舉個例子:

android {
    ...

    defaultConfig {
        minSdkVersion 8
        versionCode 10
    }

    productFlavors {
        flavor1 {
            packageName "com.example.flavor1"
            versionCode 20
        }

        flavor2 {
            packageName "com.example.flavor2"
            minSdkVersion 14
        }
    }
}

這樣就可以輸出兩個定製的apk,不同包名,版本號也不同。 但是,如果用它來打渠道包是一個非常低效的做法,因為它每一次都會走編譯流程,你想一下如果每打一個渠道包就要走一下編譯流程,100個渠道包那得多慢。

那如果你能忍受這麼低效打渠道包的方式,那回到本文焦點,我先問個問題:“如果你要針對多渠道進行打補丁,你應該怎麼做?”

你可能會回答,那就針對不同的渠道包進行打補丁。沒錯,這個確實行得通,Bugly也是支援以這種方式進行打補丁,tinker-support外掛會為不同渠道包插入不同的TINKER_ID, 唯一標識當前版本的渠道包,我們可以看下gradle打多渠道補丁的配置(詳細參考多渠道熱更新

):

這裡寫圖片描述

這裡寫圖片描述

上面的示例只是配置了兩個渠道,如果你配置超過5個的話,那麼就意味著你要一個補丁,一個補丁上傳到Bugly補丁管理後臺,況且我們也只允許同時下發5個版本的補丁。這裡提一下為什麼要上傳所有渠道的補丁,因為通過productFlavors配置,會修改buildConfig類中的FLAVOR欄位,這會導致生成的不同渠道包的dex是不一樣的,所以只能針對具體渠道進行打補丁。這就非常的尷尬了,那怎麼辦呢?有沒有版本通過一個補丁就能夠修復所有渠道,答案是:有的,但前提是你要保證所有渠道包程式碼是一致的

通過多渠道打包框架快速打多渠道包

這裡推薦使用walle來打多渠道包,新一代多渠道打包神器。

通過walle或者類似的打包工具就不會改變dex的結構,只是修改APK Signature Block來新增自定義的渠道資訊來生成渠道包。

配置示例:

// 多渠道使用walle示例(注:多渠道使用)
apply from: 'multiple-channel.gradle'

建立multiple-channel.gradle,內容如下:

apply plugin: 'walle'

walle {
    // 指定渠道包的輸出路徑
    apkOutputFolder = new File("${project.buildDir}/outputs/channels");
    // 定製渠道包的APK的檔名稱
    apkFileNameFormat = '${appName}-${packageName}-${channel}-${buildType}-v${versionName}-${versionCode}-${buildTime}.apk';
    // 渠道配置檔案
    channelFile = new File("${project.getProjectDir()}/channel")
}

建立channel配置:

這裡寫圖片描述

命令列打多渠道包:

./gradlew clean assembleReleaseChannels

輸出結果如下:

這裡寫圖片描述

ok,到此已經實現快速打多渠道包了。

如何獲取渠道資訊?

如果你想獲取渠道資訊進行一些統計的分析,可以按照以下方式(具體參考walle):

dependencies {
    compile 'com.meituan.android.walle:library:1.1.3'
}

在程式碼中獲取渠道資訊:

String channel = WalleChannelReader.getChannel(this.getApplicationContext());

如果你已經集成了Bugly的異常上報,你就可以通過以下方式來塞入渠道資訊:

 String channel = WalleChannelReader.getChannel(getApplication());
 Bugly.setAppChannel(getApplication(), channel);
  // 這裡實現SDK初始化,appId替換成你的在Bugly平臺申請的appId
 Bugly.init(getApplication(), "YOUR_APP_ID", true);

這樣我們就可以按渠道維度來統計你們app的Crash資料了。

一個補丁修復所有渠道

重頭戲,總是留在最後。 在打渠道包的過程,因為會走編譯流程,熱更新外掛也會在bakApk生成對應的基線版本,這個跟普通打包就沒有差別了:

這裡寫圖片描述

只需要上傳補丁包到補丁管理後臺,然後下發即可。

筆者隨便挑了三個渠道分別安裝到不同裝置,均成功打上補丁:

這裡寫圖片描述

ok,基本上我們的需求就已經實現啦,媽媽再也不用擔心我加班加點上傳補丁包了。

總結

Bugly目前同時支援兩種方式進行渠道包的熱更新:

  • productFlavors方式打多渠道包
  • 快速打渠道包工具(Gradle)

筆者是推薦使用第二種方式,不僅能夠快速打包,也能夠輕鬆實現一個補丁修復所有渠道。

如果大家對以上有什麼疑問的話,可以在下面留言,我們共同探討下。