如何讓Android App實現(xiàn)自動瘦身

利用gradle腳本驅(qū)動python腳本在打包時執(zhí)行項目全局圖片自動壓縮,達到精簡apk包的大小。

1、背景

為什么要做自動化壓縮圖片?設計給的切圖多半是采用png格式,就算使用png的有損壓縮也是九牛一毛,但是webp的壓縮效果就很明顯,一個png直接轉(zhuǎn)換成webp壓縮效率平均有70%以上,這個開發(fā)一般都知道。當然我們直接把圖片放到項目中點擊右鍵也可以直接轉(zhuǎn)換成webp,但是這種操作難免效率低下影響開發(fā),而且有時候可能會忘記壓縮。所以萌生了在打包或者上線前添加一個主動壓縮圖片的流程的想法。

2、如何做

既然涉及到自動化,就免不了使用Jenkins,Python一開始最先想到的是這個過程入手,但是Jenkins在構建后流程中加入指令是比較方便的,一些對打好包的自動化流程就比較方便,比如自動化加固,自動化批量簽名渠道包等等。但是想在構建前加入指令就不是很方便了。
所以這里我采用的是從Gradle入手,因為以前在Gradle中做過其他的自動化構建流程。
這里的想法是使用Gradle中加入新的打包任務在執(zhí)行完圖片壓縮之后,在執(zhí)行打包流程。
這里還需要一個Webp轉(zhuǎn)化工具:官方鏈接
看文檔命令比較簡單 一般我們可能會用的參數(shù)主要是-q,也可以采用默認值,也是官方的標準值

cwebp [options] input_file -o output_file.webp

-q float指定 RGB 通道在 0 和 100 之間的壓縮因數(shù)。默認值為 75。在使用有損壓縮(默認)的情況下,一個小因素會導致質(zhì)量較低的較小文件。使用 100 值可以實現(xiàn)最佳質(zhì)量。對于無損壓縮(通過 -lossless 選項指定),較小的因素可以提高壓縮速度,但生成的文件也較大。通過使用 100 值來實現(xiàn)最大壓縮

2.1、編寫Python腳本

這里我們需要Python,至于怎么安裝太簡單了,就不細說了。
python這里我們也可以采用image庫里的PIL對png進行預壓縮然后再轉(zhuǎn)Webp,效果會好一點點,也就好一點點,所以我沒用。然后Python主要思路是遍歷項目指定目錄的png文件,然后自動轉(zhuǎn)換并替換原來的源文件。

if __name__ == "__main__":

    if os.getcwd().endswith("tools"):
        projectPath = "/".join(os.getcwd().split("/")[:-1])
    else:
        projectPath = os.getcwd()

    print(projectPath + "/../app")
    convert2WebpInDirectory(projectPath + "/../app")
    # convert2WebpInDirectory(projectPath + "/common")
    # convert2WebpInDirectory(projectPath + "/resource")
    # convert2WebpInDirectory(projectPath + "/market")

    print("\n\n==> convert " + str(len(result)) + " png to webp")
    print(result)

這邊我采用的相對目錄從os.getcwd獲取項目根目錄。
腳本是在項目根目錄里建了一個Script文件夾存放python腳本,自動化python腳本都是放在這個目錄下。
然后遍歷指定的目錄去尋找png圖片的時候注意忽略.9圖,Build目錄,asset目錄下的圖片。

def convert2WebpInDirectory(dir):
    print(" ------> begin:",dir)

    if os.path.isdir(dir):
        allfiles = os.listdir(dir)
        for fi in allfiles:
            #print(" ------> fi:", fi)
            fi_d = os.path.join(dir, fi)
            if os.path.isdir(fi_d):
                convert2WebpInDirectory(fi_d)
            else:
                if fi_d.endswith(".png"):
                    print("fi_d:", fi_d)
                    png = fi_d
                    if png.find(".9.png") > 0:
                        continue
                    if png.find("build/intermediates/") > 0:
                        continue
                    if png.find("assets/images/") > 0:
                        continue
                    print(" ------> png:", png)
                    filename = png.split("/")[-1].replace(".png", ".webp")
                    print(" ------> filename:", filename)
                    filedir = "/".join(png.split("/")[:-1])
                    webp = "%s/%s" % (filedir, filename)
                    print(" ------> webp:", webp)
                    commandline = "%s/../tools/libwebp-0.4.1/bin/cwebp -q 80 %s -o %s" % (projectPath, png, webp)
                    os.system(commandline)
                    result.append(webp.split("/")[-1])
                    os.remove(png)
                    print(webp + " ------> sucess")

2.2 編寫Gradle腳本

在項目根目錄下創(chuàng)建autoRelease.gradle文件

 def projectPath = "."
 def zipPath = "${projectPath}/tools/libwebp-0.4.1.zip"  //rootProject.ext.jiagu["unzipPath"]
 def unzipPath = "${projectPath}/tools"                  //rootProject.ext.jiagu["unzipPath"] 
 def jarPath = "${projectPath}/tools/libwebp-0.4.1"      //rootProject.ext.jiagu["unzipPath"]

編寫2個新的打包任務,依賴預處理任務preHandleBeforeRelease,打測試包app:assembleDebug,打正式包

app:assembleDebug

任務分類為build這樣我們就可以在gradle列表里的build文件夾看到了。這個任務主要是判斷cwebp可執(zhí)行文件是否解壓了,沒有解壓則先解壓。

task releaseDebugAuto(dependsOn: ['preHandleBeforeRelease','app:assembleDebug']){
    group = "build"

    def jarFile = file(jarPath)

    if (jarFile.exists()) {
        return
    }

    //解壓 Zip 文件
    ant.unzip(src: zipPath, dest: unzipPath, encoding: "utf-8")
    //將解壓后的文件開啟讀寫權限,防止執(zhí)行 Jar 文件沒有權限執(zhí)行
    if(!Os.isFamily(Os.FAMILY_WINDOWS) && !Os.isFamily(Os.FAMILY_MAC)){
        exec {
            executable = 'chmod'
            args = ['-R', '777', unzipPath]
        }
    }
}

預處理任務,則是在保證壓縮包ok的情況下,執(zhí)行Python腳本。

這里為了保證py文件依賴的三方庫存在,執(zhí)行了requirements.text,壓縮webp這個文件里是空的。

生成這個文件也很簡單,在編寫完腳本之后再py項目里執(zhí)行

pip freeze -> requirements.txt

就可以了。

task preHandleBeforeRelease(){
    exec {
        workingDir = "${projectPath}/Script"
        commandLine = ['python3','-m','pip','install','-r','requirements.txt']
    }

    exec {
        workingDir = "${projectPath}/Script"
        commandLine = ['python3','png2webp.py']
    }
}

好了這里基本所有的主要步驟都ok了,執(zhí)行一下打包命令。

轉(zhuǎn)換結果

我這里因為png已經(jīng)全部轉(zhuǎn)換完畢,所以convert 0 png,執(zhí)行成功。

最后一步打開Jenkins,配置自動打包任務。

Jenkins配置
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容