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

一、使用Androis Studio自帶的productFlavors

productFlavors的功能非常強(qiáng)大,但用起來真的太慢偎巢,即使不是很大的項目,你也受不了那個速度兼耀。之所以慢压昼,也是因為他的強(qiáng)大求冷。比較適合Google play發(fā)布吧,畢竟人家支持根據(jù)機(jī)型下載不同的安裝包(比如按平臺打包so文件)窍霞。國內(nèi)的情況匠题,一般都不支持,渠道也只不過是用一個字符串區(qū)分但金,其他都一樣韭山。確實沒必要用productFlavors。這里還是記錄下用法:

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

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

    }

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

2、AndroidManifest下application標(biāo)簽下添加

<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味赃、先說些相關(guān)的

這里推薦一片文章,關(guān)于V1攀唯,V2簽名洁桌,以及多渠道打包工具的原理:
借騰訊開源 VasDolly,談?wù)?Android 簽名和多渠道打包的原理
VasDolly Github網(wǎng)址:
https://github.com/Tencent/VasDolly
詳細(xì)的使用方法侯嘀,上面的網(wǎng)址里的文檔已經(jīng)寫的很清楚了另凌。有一個注意點(diǎn)就是目前按照github文檔(2018/3/9)根據(jù)基礎(chǔ)包生成多渠道包的rebuildChannel不能配置文件名,實際上也是可以的戒幔,但不是那么直接(這里和維護(hù)的工程師交流過了吠谢,說會加上說明)。

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")
  //快速模式:生成渠道包時不進(jìn)行校驗(速度可以提升10倍以上)
  isFastMode = false
}

文檔里沒有說明的一個規(guī)則:渠道名會替換基礎(chǔ)包名稱里的base字符串诗茎。
以上面的配置為例工坊,假設(shè)你有渠道名是kuan,那么執(zhí)行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王污、結(jié)合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
    //這里的目錄都是自己定義的阱驾,我這里是動態(tài)的設(shè)置包的名稱的就谜,由于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")
    //快速模式:生成渠道包時不進(jìn)行校驗(速度可以提升10倍以上)
    isFastMode = false
}

andResGuard {
    // mappingFile = file("./resource_mapping.txt")
    mappingFile = null
    // 使用v2簽名和7zip壓縮是沖突的(但他是不會報錯的)里覆。
    // 如果用了V2丧荐,這里就必須false,不然生成的包無法安裝喧枷。
    use7zip = false
    useSign = true
    // 打開這個開關(guān)虹统,會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"
    }
    //這里配置的是輸出的目錄割去,名稱是動態(tài)的窟却,可以參考下這種寫法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 {
        //在這里配置相關(guān)的簽名信息
        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
生成基礎(chǔ)包,然后rebuildChannel生成多渠道包握础,收工辐董。
也可以編輯gradle task,做成一個task搞定(其實沒多大差別了)禀综。


操作步驟
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末简烘,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子定枷,更是在濱河造成了極大的恐慌孤澎,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,332評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件欠窒,死亡現(xiàn)場離奇詭異覆旭,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)岖妄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,508評論 3 385
  • 文/潘曉璐 我一進(jìn)店門型将,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人荐虐,你說我怎么就攤上這事七兜。” “怎么了缚俏?”我有些...
    開封第一講書人閱讀 157,812評論 0 348
  • 文/不壞的土叔 我叫張陵惊搏,是天一觀的道長贮乳。 經(jīng)常有香客問我,道長恬惯,這世上最難降的妖魔是什么向拆? 我笑而不...
    開封第一講書人閱讀 56,607評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮酪耳,結(jié)果婚禮上浓恳,老公的妹妹穿的比我還像新娘。我一直安慰自己碗暗,他們只是感情好颈将,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,728評論 6 386
  • 文/花漫 我一把揭開白布屠阻。 她就那樣靜靜地躺著茂腥,像睡著了一般袍祖。 火紅的嫁衣襯著肌膚如雪捡硅。 梳的紋絲不亂的頭發(fā)上呻率,一...
    開封第一講書人閱讀 49,919評論 1 290
  • 那天踊沸,我揣著相機(jī)與錄音苛蒲,去河邊找鬼笋颤。 笑死勤篮,一個胖子當(dāng)著我的面吹牛都毒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播碰缔,決...
    沈念sama閱讀 39,071評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼账劲,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了金抡?” 一聲冷哼從身側(cè)響起瀑焦,我...
    開封第一講書人閱讀 37,802評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎竟终,沒想到半個月后蝠猬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,256評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡统捶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,576評論 2 327
  • 正文 我和宋清朗相戀三年榆芦,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片喘鸟。...
    茶點(diǎn)故事閱讀 38,712評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡匆绣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出什黑,到底是詐尸還是另有隱情崎淳,我是刑警寧澤,帶...
    沈念sama閱讀 34,389評論 4 332
  • 正文 年R本政府宣布愕把,位于F島的核電站拣凹,受9級特大地震影響森爽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜嚣镜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,032評論 3 316
  • 文/蒙蒙 一爬迟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧菊匿,春花似錦付呕、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至佩厚,卻和暖如春姆钉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背抄瓦。 一陣腳步聲響...
    開封第一講書人閱讀 32,026評論 1 266
  • 我被黑心中介騙來泰國打工育韩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人闺鲸。 一個月前我還...
    沈念sama閱讀 46,473評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像埃叭,于是被迫代替她去往敵國和親摸恍。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,606評論 2 350