Android 多渠道打包實踐(VasDolly&AndResGuard)

一、使用Androis Studio自帶的productFlavors

productFlavors的功能非常強大,但用起來真的太慢,即使不是很大的項目,你也受不了那個速度。之所以慢,也是因為他的強大。比較適合Google play發布吧,畢竟人家支持根據機型下載不同的安裝包(比如按平臺打包so文件)。國內的情況,一般都不支持,渠道也只不過是用一個字符串區分,其他都一樣。確實沒必要用productFlavors。這里還是記錄下用法:

1、在app module 的builde.gradle 的android{}閉包下配置

//多渠道打包,下面是需要配置的渠道,名稱自定義,自己能區分就行
    productFlavors {
        alphaTest {}
        alibaba {}
        xiaomi {}
        googlePlay {}
        official {}
        yingyongbao{}
        huawei{}
        qh360 {}
        baidu {}
        kuan {}

    }

    productFlavors.all {//會替換AndroidManifest下配置的變量,達到區分不同渠道的目的
        flavor -> flavor.manifestPlaceholders = [STORE_CHANNEL_VALUE: name]
    }

2、AndroidManifest下application標簽下添加

<meta-data
      android:name="STORE_CHANNEL"
      android:value="${STORE_CHANNEL_VALUE}"/>

3、獲取渠道信息的方法

//可能返回空,需要自己判斷
 public static String getAppChannel(Context context) {
        ApplicationInfo appInfo;
        try {
            appInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
            return appInfo.metaData.getString("STORE_CHANNEL");
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return null;
        }
    }

二、使用一些開源的工具,這里推薦騰訊的VasDolly

1、先說些相關的

這里推薦一片文章,關于V1,V2簽名,以及多渠道打包工具的原理:
借騰訊開源 VasDolly,談談 Android 簽名和多渠道打包的原理
VasDolly Github網址:
https://github.com/Tencent/VasDolly
詳細的使用方法,上面的網址里的文檔已經寫的很清楚了。有一個注意點就是目前按照github文檔(2018/3/9)根據基礎包生成多渠道包的rebuildChannel不能配置文件名,實際上也是可以的,但不是那么直接(這里和維護的工程師交流過了,說會加上說明)。

rebuildChannel {
  //指定渠道文件
  //channelFile = file("/Users/leon/Downloads/testReChannel.txt")
  //注意這個文件名base.apk
  baseReleaseApk = new File("C:/Android/Project-3.0/ProjectName/", "apk-base/base.apk"
  releaseOutputDir = new File(project.buildDir, "rebuildChannel/release")
  //快速模式:生成渠道包時不進行校驗(速度可以提升10倍以上)
  isFastMode = false
}

文檔里沒有說明的一個規則:渠道名會替換基礎包名稱里的base字符串。
以上面的配置為例,假設你有渠道名是kuan,那么執行rebuildChannel后的輸出的文件名就是kuan.apk(base--->kuan)。
如果上面的baseReleaseApk名稱做下修改:

baseReleaseApk = new File("C:/Android/Project-3.0/ProjectName/", 
"apk-base/app_base_V1.0_release.apk"

那么最后輸出的文件名就是app_kuan_V1.0_release.apk

2、結合AndResGuard使用VasDolly

2.1、添加依賴
Project的build.gradle

buildscript {
    repositories {
        jcenter()
        google()
        maven { url 'https://jitpack.io' }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.1'
        classpath 'com.tencent.mm:AndResGuard-gradle-plugin:1.2.11'
        classpath 'com.leon.channel:plugin:1.1.7'
    }
}

主module app的build.gradle添加插件

apply plugin: 'AndResGuard'
apply plugin: 'channel'

主module app的build.gradle添加依賴(只有這一個,用于獲取渠道信息,其他方面這兩個工具都不涉及編譯過程)

dependencies {
    api 'com.leon.channel:helper:1.1.7'
}

主module app的build.gradle 配置

rebuildChannel {//從此,打包效率提高十倍以上,即使不開FastMode
    //這里的目錄都是自己定義的,我這里是動態的設置包的名稱的,由于versionName比較長,就截取了一段
    baseDebugApk = new File("C:/Android/Project-3.0/ProjectName/", "apk-base/denglu1-" +
            "${android.defaultConfig.versionName.substring(0, 6)}-base-debug.apk")
    debugOutputDir = new File("C:/Users/Bright/Desktop/", "rebuildChannel/debug")
    baseReleaseApk = new File("C:/Android/Project-3.0/ProjectName/", "apk-base/denglu1-" +
            "${android.defaultConfig.versionName.substring(0, 6)}-base-release.apk")
    releaseOutputDir = new File("C:/Users/Bright/Desktop/", "rebuildChannel/release")
    //快速模式:生成渠道包時不進行校驗(速度可以提升10倍以上)
    isFastMode = false
}

andResGuard {
    // mappingFile = file("./resource_mapping.txt")
    mappingFile = null
    // 使用v2簽名和7zip壓縮是沖突的(但他是不會報錯的)。
    // 如果用了V2,這里就必須false,不然生成的包無法安裝。
    use7zip = false
    useSign = true
    // 打開這個開關,會keep住所有資源的原始路徑,只混淆資源的名字
    keepRoot = false
    whiteList = [
            "R.mipmap.ic_launcher",
            "R.mipmap.ic_launcher_round",
            "R.drawable.push_small"
    ]
    compressFilePattern = [
            "*.png",
            "*.jpg",
            "*.jpeg",
            "*.gif",
            "resources.arsc"
    ]
    sevenzip {
        artifact = 'com.tencent.mm:SevenZip:1.2.11'
        //path = "/usr/local/bin/7za"
    }
    //這里配置的是輸出的目錄,名稱是動態的,可以參考下這種寫法buildTypes就是release/debug/...看你配置了幾種了
    finalApkBackupPath = "C:/Android/Project-3.0/ProjectName/apk-base/denglu1-" +
            "${android.defaultConfig.versionName.substring(0, 6)}" +
            "-base-" +
            "release.apk"
}

主module app的build.gradle android{}閉包里配置簽名信息,這里同時使用了V1、V2簽名:

signingConfigs {
        //在這里配置相關的簽名信息
        keyStore {
            Properties properties = new Properties()
            properties.load(project.rootProject.file('local.properties').newDataInputStream())
            def keystoreFilePath = properties.getProperty("KEY_STORE_FILE_PATH")
            def storePsw = properties.getProperty("KEY_STORE_PASSWORD")
            def alias = properties.getProperty("KEY_ALIAS")
            def keyPsw = properties.getProperty("KEY_PASSWORD")

            storeFile file(keystoreFilePath)
            storePassword storePsw
            keyAlias alias
            keyPassword keyPsw
            v1SigningEnabled true
            v2SigningEnabled true
        }
    }

channel.txt:

alibaba
xiaomi
googlePlay
official
yingyongbao
huawei
qh360
baidu

channel.txt我是放在Project根目錄下,然后在gradle.properties里配置的:

channel_file=channel.txt

你也可以在rebuildChannel{}閉包里配置,具體參照VasDolly的Github文檔
獲取渠道信息的方法:

public static String getAppChannel(Context context) {
        String channel = ChannelReaderUtil.getChannel(context.getApplicationContext());
        if (channel == null) {//防止debug直接安裝時,獲取為空,事實上,也只有release時才需要多渠道
            return "alphaTest";
        } else {
            return channel;
        }
    }

最后,先resguardRelease
生成基礎包,然后rebuildChannel生成多渠道包,收工。
也可以編輯gradle task,做成一個task搞定(其實沒多大差別了)。


操作步驟
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,156評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,401評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,069評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,873評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,635評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,128評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,203評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,365評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,881評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,733評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,935評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,475評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,172評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,582評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,821評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,595評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,908評論 2 372