Android Gradle腳本解決美團多渠道打包再加固渠道信息丟失問題

1、關於美團多渠道打包

在Android開發中,確定少不了要打多渠道包。Umeng有提供一些多渠道打包的方式,可是太慢了,每一個渠道都要重複的去打,若是有50多個渠道,就須要編譯50乘以1個包編譯的時間。So,確定是不可能這樣乾的,這個方案只適合一些渠道比較少的。因此個人項目裏採用的美團的多渠道打包的方式。java

具體的能夠移動至個人另外一篇文章:Android美團多渠道打包Walle集成git

2、爲何又新寫了這一篇文章?

就如標題所示,原本萬事大吉了,能夠一鍵生成多渠道包。**但是等到發佈的時候測試和我說,渠道信息沒有了,What???**而後網上各類翻資料,去Walle項目看看有沒有相似的問題。不出所料,Walle官網也給出了緣由和具體的解決方案。github

360加固致使渠道信息丟失問題解決方案shell

但是這個方案,太蛋疼了哥。我每次都要手動的打Release包,而後上傳360加固,下載加固包。而後本地跑一次Phtyon腳本生成渠道包。請告訴我這個操做蛋疼不?緩存

有沒有啥辦法能夠在Android Studio裏也一鍵生成多渠道包而且渠道信息也不會丟失呢?固然是有的,本身動手豐衣足食。bash

把上述這些步驟所有寫在一個Gradle腳本里,主模塊Gradle apply本身的寫的腳本。markdown

3、自定義360加固+Walle打包腳本

一、首先在工程主模塊新建reinforce.gradle腳本

reinforce.gradle.png

二、複製加固文件夾到項目根目錄

(1)配置加固文件夾 把從360加固官網下載的window下載(MAC環境就MAC下載)裏的內容有個jiagu文件夾,複製到工程目錄,而且更名爲reinforce,這裏隨意我是這樣命名的。而後把美團的walle-cli-all.jar複製到reinforce文件夾裏lib文件夾下。 app

加固文件夾.png
(2)配置渠道信息 在reinforce文件夾下新增channel.txt文件。錄入你想要的渠道的信息

baidu #百度
xiaomi # 小米
anzhi # 安智
meizu # 魅族
vivo # vivo
oppo # oppo
huawei # 華爲
sougou # 搜狗
samsung # 三星
lianxiang # 聯想
jinli # 金立
taobao #淘寶
yingyongbao #應用寶
360 #360
anzhi #安智
guanwang #官網
複製代碼

或者直接下我弄好的:(Window) 連接: pan.baidu.com/s/1jw_0Wya4… 提取碼: igx9oop

三、reinforce.gradle腳本內容以下,ext寫入項目相關的一些信息。其餘的應該都不用動。

(1) Window下的腳本測試

ext {
    //加固插件路徑
    reinforce_plugin_path = '../reinforce'
   //360加固帳號密碼
    reinforce_plugin_name = 'XXXXX'
    reinforce_plugin_passward = 'XXXXXX'
    //簽名信息
    key_store_path = './xyz.keystore'
    key_store_passward = 'XXXXX'
    alias = 'XXXXXX'
    alias_passward = 'XXXXX'
    //加固ApK輸出路徑
    reinforce_apk_path = 'build/outputs/apk/release/reinforce/'
    //加固包名稱
    reinforce_apk_name = 'build/outputs/apk/release/reinforce/release_encrypted_aligned_signed.apk'
    //渠道配置文件
    chanel_config_path = reinforce_plugin_path + '/channel.txt'
    //渠道Apk輸出路徑
    channel_apks_path = 'build/outputs/apk/release/channels/'
}

/** * 註釋:編譯加固渠道包 * 時間:2019/1/2 0002 14:01 * 做者:郭翰林 */
task buildReinforceRelease() {
    group '360reinforce'
    dependsOn('assembleRelease')
    doLast {
        //第一步:清空緩存
        cleanFilesPath(reinforce_plugin_path + "/.cache")
        cleanFilesPath(reinforce_plugin_path + "/output")
        cleanFilesPath(reinforce_plugin_path + "/jiagu.db")
        cleanFilesPath(reinforce_apk_path)
        cleanFilesPath(channel_apks_path)
        //第二步:開始加固
        reinforceApk()
        //第三部:重命名加固包
        renameReinforceApk()
        //第四步:打多渠道包
        buildChannelApks()
    }
}

/** * 註釋:打多渠道包 * 時間:2019/1/4 0004 13:26 * 做者:郭翰林 */
def buildChannelApks() {
    println('開始編譯多渠道包')
    File reinforceApk = new File(reinforce_apk_name)
    if (!reinforceApk.exists()) {
        return
    }
    //新建渠道包目錄
    File channelsPath = new File(channel_apks_path)
    if (!channelsPath.exists()) {
        channelsPath.mkdir()
    }
    exec {
        commandLine "powershell", "java -jar", reinforce_plugin_path + "/lib/walle-cli-all.jar batch -f ", chanel_config_path, reinforce_apk_name, channel_apks_path
    }
    println('編譯多渠道包成功,生成的渠道包路徑:' + channelsPath.getAbsolutePath())
}

/** * 註釋:重命名已加固好的APK * 時間:2019/1/4 0004 12:48 * 做者:郭翰林 */
def renameReinforceApk() {
    File files = new File('build/outputs/apk/release/reinforce')
    if (!files.exists()) {
        return
    }
    if (files.isDirectory()) {
        String[] content = files.list()//取得當前目錄下全部文件和文件夾
        for (String name : content) {
            //因爲第一步清空緩存,reinforce文件夾內只會有一個已經加固而且簽名的包
            File signedApk = new File('build/outputs/apk/release/reinforce', name)
            File renameApk = new File(reinforce_apk_name)
            if (signedApk.exists() && signedApk.isFile()) {
                signedApk.renameTo(renameApk)
            }
        }
    }
}

/** * 註釋:使用360加固加固Release包 * 時間:2019/1/2 0002 14:32 * 做者:郭翰林 */
def reinforceApk() {
    println('開始進行加固操做')
    File releaseApk = new File('build/outputs/apk/release/app-release.apk')
    if (!releaseApk.exists()) {
        throw new FileNotFoundException('Release包不存在,沒法進行加固操做')
    }
    String releasePath = 'build/outputs/apk/release/app-release.apk'
    //建立加固文件夾
    File reinforcePath = new File(reinforce_apk_path)
    if (!reinforcePath.exists()) {
        reinforcePath.mkdir()
    }
    exec {
        commandLine "powershell", "java -jar", reinforce_plugin_path + "/jiagu.jar", "-login", reinforce_plugin_name, reinforce_plugin_passward
    }
    exec {
        commandLine "powershell", "java -jar", reinforce_plugin_path + "/jiagu.jar", "-importsign", key_store_path, key_store_passward, alias, alias_passward
    }
    exec {
        commandLine "powershell", "java -jar", reinforce_plugin_path + "/jiagu.jar", "-jiagu", releasePath, reinforce_apk_path, "-autosign"
    }
    println('加固操做結束,加固包路徑' + reinforcePath.getAbsolutePath())
}

/** * 註釋:清空文件夾 * 時間:2019/1/2 0002 14:15 * 做者:郭翰林 */
def cleanFilesPath(String path) {
    File files = new File(path)
    if (!files.exists()) {
        return
    }
    println('開始執行清除:' + files.getAbsolutePath())
    if (files.isDirectory()) {
        String[] content = files.list()//取得當前目錄下全部文件和文件夾
        for (String name : content) {
            File temp = new File(path, name)
            if (temp.isDirectory()) {//判斷是不是目錄
                cleanFilesPath(temp.getAbsolutePath())//遞歸調用,刪除目錄裏的內容
                temp.delete()
            } else {
                temp.delete()
            }
        }
    }
    files.delete()
}
複製代碼

(2)MAC環境下腳本

ext {
    //加固插件路徑
    reinforce_plugin_path = "${project.rootDir}/reinforce"
    reinforce_plugin_name = 'xxxxxx'
    reinforce_plugin_passward = 'xxxxxxx'
    //簽名信息
    key_store_path = "${project.rootDir}/app/xyz.keystore"
    key_store_passward = 'xxxxxxx'
    alias = 'xxxxx'
    alias_passward = 'xxxxxxxx'
    //Release Apk輸出路勁
    release_apk_path = "${project.buildDir}/outputs/apk/release/app-release.apk"
    //加固ApK輸出路徑
    reinforce_apk_path = "${project.buildDir}/outputs/apk/release/reinforce/"
    //加固包名稱
    reinforce_apk_name = "${project.buildDir}/outputs/apk/release/reinforce/release_encrypted_aligned_signed.apk"
    //渠道配置文件
    chanel_config_path = "${reinforce_plugin_path}/channel.txt"
    //渠道Apk輸出路徑
    channel_apks_path = "${project.buildDir}/outputs/apk/release/channels/"
}

/** * 註釋:編譯加固渠道包 * 時間:2019/1/2 0002 14:01 * 做者:郭翰林 */
task buildReinforceRelease() {
    group '360reinforce'
    dependsOn('assembleRelease')
    doLast {
        //第一步:清空緩存
        cleanFilesPath(reinforce_plugin_path + "/.cache")
        cleanFilesPath(reinforce_plugin_path + "/output")
        cleanFilesPath(reinforce_plugin_path + "/jiagu.db")
        cleanFilesPath(reinforce_apk_path)
        cleanFilesPath(channel_apks_path)
        //第二步:開始加固
        reinforceApk()
        //第三部:重命名加固包
        renameReinforceApk()
        //第四步:打多渠道包
        buildChannelApks()
        //清除無用緩存
        cleanFilesPath(reinforce_plugin_path + "/.cache")
        cleanFilesPath(reinforce_plugin_path + "/output")
        cleanFilesPath(reinforce_plugin_path + "/jiagu.db")
    }
}

/** * 註釋:打多渠道包 * 時間:2019/1/4 0004 13:26 * 做者:郭翰林 */
def buildChannelApks() {
    println('開始編譯多渠道包')
    File reinforceApk = new File(reinforce_apk_name)
    if (!reinforceApk.exists()) {
        return
    }
    //新建渠道包目錄
    File channelsPath = new File(channel_apks_path)
    if (!channelsPath.exists()) {
        channelsPath.mkdir()
    }
    exec {
        commandLine "bash", "-c", "java -jar ${reinforce_plugin_path}/lib/walle-cli-all.jar batch -f ${chanel_config_path} ${reinforce_apk_name} ${channel_apks_path}"
    }
    println('編譯多渠道包成功,生成的渠道包路徑:' + channelsPath.getAbsolutePath())
}

/** * 註釋:重命名已加固好的APK * 時間:2019/1/4 0004 12:48 * 做者:郭翰林 */
def renameReinforceApk() {
    File files = new File(reinforce_apk_path)
    if (!files.exists()) {
        return
    }
    if (files.isDirectory()) {
        String[] content = files.list()//取得當前目錄下全部文件和文件夾
        for (String name : content) {
            //因爲第一步清空緩存,reinforce文件夾內只會有一個已經加固而且簽名的包
            File signedApk = new File(reinforce_apk_path, name)
            File renameApk = new File(reinforce_apk_name)
            if (signedApk.exists() && signedApk.isFile()) {
                signedApk.renameTo(renameApk)
            }
        }
    }
}

/** * 註釋:使用360加固加固Release包 * 時間:2019/1/2 0002 14:32 * 做者:郭翰林 */
def reinforceApk() {
    println('開始進行加固操做')
    File releaseApk = new File(release_apk_path)
    if (!releaseApk.exists()) {
        throw new FileNotFoundException("Release包不存在,沒法進行加固操做,文件路徑:${releaseApk.getAbsolutePath()}")
    }
    //建立加固文件夾
    File reinforcePath = new File(reinforce_apk_path)
    if (!reinforcePath.exists()) {
        reinforcePath.mkdir()
    }
    exec {
        commandLine "bash", "-c", "chmod +x ${reinforce_plugin_path}/java/bin/*"
    }
    exec {
        commandLine "bash", "-c", "java -jar ${reinforce_plugin_path}/jiagu.jar -login ${reinforce_plugin_name} ${reinforce_plugin_passward}"
    }
    exec {
        commandLine "bash", "-c", "java -jar ${reinforce_plugin_path}/jiagu.jar -importsign ${key_store_path} ${key_store_passward} ${alias} ${alias_passward}"
    }
    exec {
        commandLine "bash", "-c", "java -jar ${reinforce_plugin_path}/jiagu.jar -jiagu ${release_apk_path} ${reinforce_apk_path} -autosign"
    }
    println('加固操做結束,加固包路徑' + reinforcePath.getAbsolutePath())
}

/** * 註釋:清空文件夾 * 時間:2019/1/2 0002 14:15 * 做者:郭翰林 */
def cleanFilesPath(String path) {
    File files = new File(path)
    if (!files.exists()) {
        return
    }
    println('開始執行清除:' + files.getAbsolutePath())
    if (files.isDirectory()) {
        String[] content = files.list()//取得當前目錄下全部文件和文件夾
        for (String name : content) {
            File temp = new File(path, name)
            if (temp.isDirectory()) {//判斷是不是目錄
                cleanFilesPath(temp.getAbsolutePath())//遞歸調用,刪除目錄裏的內容
                temp.delete()
            } else {
                temp.delete()
            }
        }
    }
    files.delete()
}
複製代碼

4、集成完畢以後,如何使用

一、查找名爲buildReinforceRelease的Task任務 二、待生成完畢以後,渠道包在主模塊下的build/outputs/apk/release/channels/文件夾下

命令使用方法.png
相關文章
相關標籤/搜索