面對(duì)那種無(wú)節(jié)操的產(chǎn)品,你們?cè)趺崔k?
產(chǎn)品:“apk的體積是否可以?xún)?yōu)化以下,這樣比較好推廣!”
我:“不可以!”
產(chǎn)品:“apk的體積是否可以?xún)?yōu)化以下,這樣比較好推廣!”
我:“不可以!”
產(chǎn)品:“apk的體積是否可以?xún)?yōu)化以下,這樣比較好推廣!”
我:“我考慮一下!”
沒(méi)辦法面對(duì)這樣的產(chǎn)品我們?cè)趺茨軕Z!老子寫(xiě)代碼都是一把梭!?。?/p>
但是回頭想想,這個(gè)和寫(xiě)代碼有個(gè)毛線(xiàn)關(guān)系?。。?/p>
好了,吐槽環(huán)節(jié)到此結(jié)束?。?!
今天我們就來(lái)討論一下,apk體積優(yōu)化的一些方式:
本文知識(shí)點(diǎn):
apk優(yōu)化的一些奇淫技巧?。?!
本文分為如下幾個(gè)步驟去優(yōu)化,有什么不對(duì)的還請(qǐng)大神們見(jiàn)諒!小弟還是個(gè)菜鳥(niǎo)。。。 哈哈 ??!
- svg的使用與優(yōu)化
- Tint著色器的使用與優(yōu)化
- 資源打包配置優(yōu)化
- 動(dòng)態(tài)庫(kù)的打包配置優(yōu)化
- 移除無(wú)用的資源(物理與非物理刪除)
- 代碼混淆
- webp轉(zhuǎn)換(api等級(jí)18)
- 資源混淆
這個(gè)需要api的等級(jí)最低為18,現(xiàn)在基本上都可以滿(mǎn)足需求!
這個(gè)使用的時(shí)候很簡(jiǎn)單,選中圖片直接右鍵,conver to Webp...直接就能轉(zhuǎn)換過(guò)來(lái)!越大的圖片轉(zhuǎn)換節(jié)約的體積也就越大!
- 資源混淆
基本上我優(yōu)化的時(shí)候就從以上幾個(gè)方面去進(jìn)行的,在和之前沒(méi)進(jìn)行優(yōu)化的項(xiàng)目比較,可以使體積減少至少30%!不信可以在你的項(xiàng)目中實(shí)驗(yàn)一下!省的說(shuō)我開(kāi)車(chē)不穩(wěn),翻車(chē)了!??!
1. svg的使用與優(yōu)化
首先我們先來(lái)了解一下什么是svg在百度百科是這么說(shuō)的?。?!,其實(shí)我們只要關(guān)注主要的概念就好了!可縮放的矢量圖形。其實(shí)人話(huà)就是在不同大小的地方顯示不變形!具體的概念,看看百度百科就好了?。?!
為了方便給大家演示!這里呢?我特意找了個(gè)網(wǎng)站阿里矢量圖,在這個(gè)網(wǎng)站中你可以下載各種的矢量圖,然后呢?就沒(méi)有然后了。。。
下載之后呢?會(huì)有一個(gè)丑丑的ie瀏覽器的圖標(biāo)后綴為.svg的東西!這個(gè)怎么用呢?強(qiáng)大的android studio 為我們做好了準(zhǔn)備工作!
res->new->vector Asset
之后會(huì)蹦出來(lái)這么個(gè)玩意
前一個(gè)紅框是系統(tǒng)的圖標(biāo),后一個(gè)是本地的圖標(biāo)!這樣你就會(huì)生成一個(gè)以.xml為結(jié)尾的圖標(biāo)了!
里面的代碼大概是這個(gè)樣子的!
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z" />
</vector>
其實(shí)里面的具體語(yǔ)法我也不太了解,應(yīng)該是在指定區(qū)域中分成寬和高的等份,然后填充的!感興趣的可以自己了解一下!
使用的話(huà),和之前的src不同了!必須這樣使用!
app:srcCompat="@drawable/ic_arrow_back_black_24dp"
這里很多人會(huì)有兩個(gè)疑問(wèn)?
- 這個(gè)和apk體積優(yōu)化有個(gè)毛線(xiàn)關(guān)系?
- 美工往往給很多張圖片,總不能一張一張轉(zhuǎn)換吧?
關(guān)于上面這兩個(gè)問(wèn)題,我們分別來(lái)說(shuō)一下:
- 首先svg是可縮放矢量圖,所以呢?你在項(xiàng)目中只要添加一張svg就可以替換相應(yīng)的之前美工給你的一套圖,一下減少了好幾張圖片,你說(shuō)是否有關(guān)系呢?其次svg轉(zhuǎn)換成xml后大小也有相應(yīng)的縮減,這個(gè)真的是成倍減少大的! 但是,但是,但是。。。這個(gè)在需要適配,適配,適配!FUCK 0.0!話(huà)說(shuō)Android在適配這點(diǎn)上真心難受!還是看解決辦法吧!在你的app->build.gradle中的defaultConfig標(biāo)簽中添加如下內(nèi)容:
//5.0的兼容適配
//5.0以下 將svg圖片生成指定維度的png圖片,下面寫(xiě)幾個(gè)就會(huì)生成幾個(gè)相應(yīng)的圖片
vectorDrawables.generatedDensities('xhdpi','xxhdpi')
//5.0以上 以上使用support-v7進(jìn)行兼容
vectorDrawables.useSupportLibrary = true
這個(gè)是我找到的解決方案,但是我編譯了一下試了試。如果我單寫(xiě)頂上那一句,會(huì)在相應(yīng)的文件夾下生成出圖片,但是加上后面這句,相應(yīng)的圖片就沒(méi)有了!我就好奇了,為什么呢?然后我找到了相應(yīng)的手機(jī)試了一下,加不加上面這句沒(méi)有什么卵用!我是在19版本上測(cè)試的!找這樣的手機(jī)真心費(fèi)勁,要不是我父母我還真找不到?。。∷阅??大家斟酌一下吧!??!
- 這個(gè)問(wèn)題,大神們?cè)缇蛶臀覀兘鉀Q了!?。?/li>
下面這個(gè)是一個(gè)批量轉(zhuǎn)換工具!話(huà)說(shuō)沒(méi)有什么事情能難倒程序員?。?!(對(duì)我失效)
MegatronKing/SVG-Android
下載這個(gè)jar包->svg2vector-cli-1.0.1.jar
然后一波小命令!??!咔咔咔
java -jar svg2vector-cli-1.0.1.jar -d D:\svg -o D:\vector
-d 指定svg文件所在目錄
-f 指定當(dāng)個(gè)svg文件
-h 設(shè)置轉(zhuǎn)換后svg高
-w 設(shè)置轉(zhuǎn)換后svg寬
-o 輸出android vector圖像目錄
然后轉(zhuǎn)換完成,然后復(fù)制就好了!?。?/p>
2. Tint著色器的使用與優(yōu)化
大家在開(kāi)發(fā)的時(shí)候不知道有沒(méi)有過(guò)這種體驗(yàn)!在使用狀態(tài)選擇器的時(shí)候,需要使用兩張一樣顏色不同的相同圖片?其實(shí)使用tint屬性完全可以搞定(但是這里指的是純色的那種圖片,那種花花綠綠的你還是乖乖弄吧,除非你想把他變成純色!)
其實(shí)真的很簡(jiǎn)單,只要在展示的圖片中添加
app:tint="顏色值"
這樣就可以改變圖片的顏色,那么狀態(tài)選擇器呢?怎么用呢?其實(shí)很簡(jiǎn)單了!下面我們來(lái)看代碼!
先來(lái)看看兩個(gè)狀態(tài)選擇器的代碼:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_arrow_back_black_24dp" android:state_pressed="true" />
<item android:drawable="@drawable/ic_arrow_back_black_24dp" android:state_pressed="false" />
</selector>
可能你會(huì)奇怪了,為什么兩個(gè)圖片是一樣的?看到后面你就懂了!
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@android:color/white" android:state_pressed="true" />
<item android:color="@android:color/black" />
</selector>
其實(shí)原理是這樣的,狀態(tài)選擇器的話(huà)呢?只要你通過(guò)tint的狀態(tài)選擇器改變圖片的顏色就可以了!
但是這里面有幾個(gè)點(diǎn)需要注意下:
- 顏色的那個(gè)狀態(tài)選擇器要方法color文件夾下;
- 設(shè)置tint的時(shí)候要使用app為前綴,否則5.0以下的會(huì)報(bào)錯(cuò);
- 如果你設(shè)置的是svg的圖片要使用srcCompat如果是正常圖片使用src就好了。
基本上這層優(yōu)化就到這里了!
3. 資源打包配置優(yōu)化
其實(shí)這個(gè)標(biāo)題說(shuō)的有點(diǎn)大,其實(shí)就是刪除不必要的語(yǔ)言?。?!
可能你們沒(méi)有留意過(guò),在你用Android Studio查看你的apk的時(shí)候,會(huì)看到這樣的東西!
在我畫(huà)框的地方,有很多中語(yǔ)言的使用?你會(huì)好奇的問(wèn)?我沒(méi)有設(shè)置過(guò)語(yǔ)言啊?這都從哪里跑出來(lái)的呢?其實(shí)實(shí)在v7包中的!其實(shí)我們一般的應(yīng)用不會(huì)涉及到這些語(yǔ)言的!所以我們只留下其中的一種或幾種就可以了。具體怎么做呢?其實(shí)就只有一行代碼。。。
在app的build.gradle中的defaultConfig中添加這樣一句就可以了!
resConfigs('zh-rCN'')
這里其實(shí)你還可以添加多個(gè),直接用逗號(hào)連接就可以了!
優(yōu)化后就變成下面這個(gè)樣子了?。。?/p>
4. 動(dòng)態(tài)庫(kù)的打包配置
其實(shí)說(shuō)到動(dòng)態(tài)庫(kù)的話(huà),基本上就是.so引入的動(dòng)態(tài)庫(kù),其實(shí)這里有很大的優(yōu)化空間!其實(shí)你可以解壓比較大型的項(xiàng)目,其實(shí)沒(méi)有那么多so文件的類(lèi)型!
平時(shí)我們開(kāi)發(fā)的時(shí)候,基本上都是這么寫(xiě)的!
sourceSets{
main{
jniLibs.srcDirs = ['libs']
}
}
然后
ndk{
abiFIlters('armeabi','armeabi-v7a','xxx'....)
}
是不是每次像導(dǎo)入百度語(yǔ)音等第三方庫(kù)的時(shí)候,說(shuō)明文檔上這么寫(xiě)的我們也就這么弄的!但是其實(shí)我們不需要這么多的架構(gòu)!
這里簡(jiǎn)單說(shuō)一下常用的幾個(gè)
armeabi 真機(jī)
x86 模擬器
其實(shí)我們真是開(kāi)發(fā)的話(huà),直接使用armeabi就可以了,如果你做那種定制化的apk的話(huà),把其它的加上還可以,但是如果正常的手機(jī)應(yīng)用的話(huà),這里只需要armeabi的就可以了!
如果你怎么不知道用哪個(gè)?你把比較大的項(xiàng)目解壓一下看看人家用哪個(gè)你就用哪個(gè)!哈哈
5. 移除無(wú)用的資源(物理與非物理刪除)
5.1 物理刪除(無(wú)法找回,慎用)
關(guān)于物理刪除其實(shí)很多都不建議這么使用,因?yàn)檫@個(gè)真的沒(méi)有什么節(jié)操!這里說(shuō)兩個(gè)問(wèn)題:
- 如果你們項(xiàng)目沒(méi)有項(xiàng)目管理的話(huà),真的不建議這么使用,因?yàn)閯h除之后你真的找不到了!是真的找不到了(如果git的話(huà),拉個(gè)分支使勁磕就可以)!
- 如果有反射或者動(dòng)態(tài)加載id的(ids.xml)的會(huì)直接刪除!可能會(huì)報(bào)錯(cuò)!
好了,前提說(shuō)好了!別到時(shí)候后刪了之后找我。。。
方案一:
Refactor->Remove Unused Resource...
這里會(huì)談個(gè)框,會(huì)有三個(gè)選項(xiàng):
- (Refactor)第一個(gè)是直接刪除了
- (Preview)第二個(gè)會(huì)在下面彈出一個(gè)提醒,讓你選擇性的刪除
- (Cancel)取消
方案二:
Analyze->Run Inspection by name
這里也會(huì)彈出個(gè)框輸入
unused ressources
然后又彈出個(gè)框,這里就按照上面的圈圈點(diǎn)點(diǎn),然后點(diǎn)OK這個(gè)時(shí)候你會(huì)發(fā)現(xiàn)底下會(huì)出現(xiàn)相應(yīng)的無(wú)用資源這個(gè)時(shí)候你看哪個(gè)不用就直接按照右邊的提示刪除就好了
再次強(qiáng)調(diào),這個(gè)是物理刪除,刪除了就沒(méi)了?。?!
5.2 非物理刪除
其實(shí)我估計(jì)google爸爸早就考慮到這個(gè)問(wèn)題了,其實(shí)還有一種非物理刪除的,是在混淆的時(shí)候!相信大家在混淆的時(shí)候都寫(xiě)過(guò)這句吧!
shrinkResources true
開(kāi)始的時(shí)候我也不知道是什么鬼,后來(lái)看別人說(shuō)這個(gè)是啟動(dòng)資源壓縮!
但是,如果你看過(guò)壓縮后的apk的話(huà),這個(gè)資源壓縮是使用了一個(gè)占位符而不是把相應(yīng)的文件刪除!
其實(shí)這個(gè)資源壓縮還有一個(gè)比較又意思的點(diǎn),可以自定義要保留的內(nèi)容:
res->raw->keep.xml 自定義要保留的東西
<resources
tools:keep="@layout/activity_main1" 保留誰(shuí)這里就可以寫(xiě)誰(shuí)
tools:shrinkMode="strict"/>
這個(gè)是看谷歌文檔中寫(xiě)的!但是真的不知道為什么還要保留?處于什么原因呢?還請(qǐng)懂的大神指點(diǎn)?。?!
6. 代碼混淆
關(guān)于這個(gè)我不準(zhǔn)備在這里講,代碼混淆網(wǎng)上一搜一大把!基本上一個(gè)固定模板加上你引入的第三方庫(kù)的混淆就ok了(注意實(shí)體類(lèi)就好了,每次我都忘)!
7. webp轉(zhuǎn)換(api等級(jí)18)
關(guān)于webp百度百科是這么解釋的。 這個(gè)需要api的等級(jí)最低為18,現(xiàn)在基本上都可以滿(mǎn)足需求!
這個(gè)使用的時(shí)候很簡(jiǎn)單,選中圖片直接右鍵,conver to Webp...直接就能轉(zhuǎn)換過(guò)來(lái)!越大的圖片轉(zhuǎn)換節(jié)約的體積也就越大!直接看相應(yīng)的轉(zhuǎn)換就可以了!
這里我多嘮叨一句,其實(shí)有這個(gè)圖片壓縮網(wǎng)站還是不錯(cuò)的!每次美工給我圖片的時(shí)候我都會(huì)選擇壓縮一下,能節(jié)省點(diǎn)體積!關(guān)鍵是這個(gè)網(wǎng)站可以批量上傳,這個(gè)才是重點(diǎn)!然后你再webp就可以了!其實(shí)我個(gè)人覺(jué)得,除非引導(dǎo)圖等...比較大的圖,否則沒(méi)有必要使用webp!個(gè)人感覺(jué)而已。。。
8. 資源混淆
關(guān)于資源混淆基本上是美團(tuán)和微信的兩大方案,我還在整理!
- 微信的方案開(kāi)源了!
- 美團(tuán)的貌似是沒(méi)有開(kāi)源,但是在相應(yīng)的技術(shù)博客中寫(xiě)了
等整理好了之后在貼出來(lái)!
基本上我現(xiàn)在的項(xiàng)目體積優(yōu)化的話(huà),就弄了這么多,還請(qǐng)大佬們指點(diǎn)!??!