Android美團多渠道打包Walle集成

1、爲何使用美團多渠道打包的方式?

  • 打包更加快速 傳統的經過productFlavors渠道包的方式,渠道10個之內還能夠接受,若是100個渠道包,每一個包須要打5Min,就是將近10個小時的打包,而採用美團Walle多渠道打包的方式只須要打一個包的時間。
  • 配置更加靈活 能夠在APK渠道包中經過配置config文件,針對於不一樣渠道包配置各個渠道定製化額外信息

2、多渠道打包原理介紹

整個APK(ZIP文件格式)會被分爲如下四個區塊:java

  • Contents of ZIP entries(from offset 0 until the start of APK Signing Block)
  • APK Signing Block
  • ZIP Central Directory
  • ZIP End of Central Directory
    apk-sections.png

這個是V2簽名包的APK包格式,新的應用簽名方案有着良好的向後兼容性,能徹底兼容低於Android 7.0(Nougat)的版本。對比舊簽名方案,它有更快的驗證速度和更安全的保護。 區塊一、三、4都是受保護區塊,不容許修改保護區塊。美團打包的方式,是在2區塊內寫入ID-value的擴展信息(渠道信息),並保存到APK中。這樣,每打一個渠道包只需複製一個APK,而後在APK中添加一個ID-value便可,這種打包方式速度很是快,對一個30M大小的APK包只須要100多毫秒(包含文件複製時間)就能生成一個渠道包,而在運行時獲取渠道信息只須要大約幾毫秒的時間。android

3、Walle的工程配置及打包方式

在位於項目的根目錄 build.gradle 文件中添加Walle Gradle插件的依賴, 以下:

buildscript {
    dependencies {
        classpath 'com.meituan.android.walle:plugin:1.1.6'
    }
}
複製代碼

並在當前App的 build.gradle 文件中apply這個插件,並添加上用於讀取渠道號的AAR

apply plugin: 'walle'

dependencies {
    compile 'com.meituan.android.walle:library:1.1.6'
}
複製代碼

配置插件

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")
}
複製代碼

配置項具體解釋:json

  • apkOutputFolder:指定渠道包的輸出路徑, 默認值爲new File("${project.buildDir}/outputs/apk")
  • apkFileNameFormat:定製渠道包的APK的文件名稱, 默認值爲 ${appName}-${buildType}-${channel}.apk 可以使用如下變量:
projectName - 項目名字
     appName - App模塊名字
     packageName - applicationId (App包名packageName)
     buildType - buildType (release/debug等)
     channel - channel名稱 (對應渠道打包中的渠道名字)
     versionName - versionName (顯示用的版本號)
     versionCode - versionCode (內部版本號)
     buildTime - buildTime (編譯構建日期時間)
     fileSHA1 - fileSHA1 (最終APK文件的SHA1哈希值)
     flavorName - 編譯構建 productFlavors 名
複製代碼

插入額外信息 channelFile只支持渠道寫入,若是想插入除渠道之外的其餘信息,請在walle配置中使用configFile安全

walle {
    // 渠道&額外信息配置文件,與channelFile互斥
	configFile = new File("${project.getProjectDir()}/config.json")
}
複製代碼

configFile是包含渠道信息和額外信息的配置文件路徑。 配置文件採用json格式,支持爲每一個channel單獨配置額外的寫入信息。markdown

{
  //extraInfo 不要出現以`channel`爲key的狀況
  /*
  不聲明extraInfo的channel默認使用的extraInfo
  若是沒有此項則沒有默認extraInfo
  */
  "defaultExtraInfo": {
    "key2": "20161213",
    "key": "20161212"
  },

  /*
    strategy:
     1. ifNone (默認適用此策略) : 僅當對應channel沒有extraInfo時生效
     2. always : 全部channel都生效,channel中extraInfo的key與defaultExtraInfo重複時,覆蓋defaultExtraInfo中的內容。
   */

  //"defaultExtraInfoStrategy": "always",

  "channelInfoList": [
    {
      "channel": "meituan",
      // 此channel將使用本身聲明的extraInfo
      /*
      此alias能夠作到寫入apk的channel是meituan,而打包時輸出的文件名是美團
      注意:alias不聲明時,walle配置apkFileNameFormat中channel就是channel,不然爲alias
      */
      "alias": "美團",
      "extraInfo": {
        "buildtime": "20161212",
        "hash": "123"
      }
    },
    {
      "channel": "360cn",
      // 此channel將使用本身聲明的extraInfo
      "extraInfo": {
        "key": "20161213"
      }
    },
    {
      "channel": "googleplay"
      // 此channel將使用defaultExtraInfo
    },
    {
      "channel": "xiaomi"
      // 此channel將使用defaultExtraInfo
    },
    {
      "channel": "meizu"
      // 此channel將使用defaultExtraInfo
    },
    {
      "channel": "wandoujia",
      "excludeDefaultExtraInfo": true
      //強制聲明不使用defaultExtraInfo,默認false
    },
    {
      "channel": "myapp",
      "excludeDefaultExtraInfo": true,
      //強制聲明不使用defaultExtraInfo,默認false
      "extraInfo": {
        // 儘管exclude default,但也能夠繼續寫入本身的。
        "key": "20161212"
      }
    }
  ]
}
複製代碼

注意:app

  • 此配置項與channelFile功能互斥,開發者在使用時選擇其一便可,二者都存在時configFile優先執行。
  • extraInfo 不要出現以channel爲key的狀況

如何獲取渠道信息:

在須要渠道等信息時能夠經過下面代碼進行獲取工具

String channel = WalleChannelReader.getChannel(this.getApplicationContext());
複製代碼

生成渠道包

AS右側點開Gradle工具欄,以下圖所示,雙擊運行Task任務 gradle

TM20181108103724.png

生成的APK渠道包,根據Walle配置文件路徑查找 ui

TM20181108103732.png

4、關於友盟統計多渠道的變動

由於友盟統計以前的多渠道統計方式是在AndroidManifast.xml文件中配合Gradle腳本productFlavors實現的多渠道信息集成。採用這種多渠道打包方式以後,productFlavors不存在了,就算沒有刪除經過原有的獲取渠道信息的方式獲取到的渠道信息也不對了。因此須要進行變動。很簡單,只需在友盟初始化的時候把Channel信息做爲參數傳入便可。以下所示:this

/** * 做者:郭翰林 * 時間:2018/6/15 0015 12:07 * 註釋:Umeng初始化配置 * * @param mAppContext * @param mUmengKey * @param mUmengChannel * @param mUmengSecret */
    public UmengModule(Context mAppContext, String mUmengKey, String mUmengChannel, String mUmengSecret) {
        this.mUmengKey = mUmengKey;
        this.mUmengChannel = mUmengChannel;
        this.mUmengSecret = mUmengSecret;
        this.mAppContext=mAppContext;
        UMConfigure.init(mAppContext, mUmengKey, mUmengChannel, UMConfigure.DEVICE_TYPE_PHONE, mUmengSecret);
    }
		
	 /** * 做者:郭翰林 * 時間:2018/6/15 0015 14:15 * 註釋:註冊友盟,不要作主進程判斷和在線程裏註冊 */
    private void registerUmeng() {
        UmengModule module = new UmengModule(sysApplication, "XXXXXXXXXXX",
                WalleChannelReader.getChannel(sysApplication), "XXXXXXXXXX");
				.........
				.........
    }
複製代碼
相關文章
相關標籤/搜索