【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】Andriod APK體積優(yōu)化_第1頁(yè)
【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】Andriod APK體積優(yōu)化_第2頁(yè)
【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】Andriod APK體積優(yōu)化_第3頁(yè)
【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】Andriod APK體積優(yōu)化_第4頁(yè)
【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】Andriod APK體積優(yōu)化_第5頁(yè)
已閱讀5頁(yè),還剩6頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】AndriodAPK體積優(yōu)化

隨著項(xiàng)目的不斷迭代,功能越來(lái)越多,構(gòu)建出來(lái)的apk文件的大小也會(huì)越來(lái)越大,這樣會(huì)導(dǎo)致在移動(dòng)網(wǎng)絡(luò)情況下下載時(shí),使用的網(wǎng)絡(luò)流量會(huì)增大,并且apk太大,導(dǎo)致下載的時(shí)間也增加,雖然當(dāng)前每個(gè)人的手機(jī)的流量都很多,對(duì)用戶流量影響不大,但是據(jù)一些網(wǎng)站統(tǒng)計(jì),安裝包越大,用戶的轉(zhuǎn)化率是在降低的,所以減少apk的體積,可以讓更多的用戶愿意去下載和體驗(yàn)產(chǎn)品。所以,對(duì)apk體積進(jìn)行瘦身還是很有必要的。在對(duì)apk體積進(jìn)行瘦身前,最好保證這個(gè)apk已經(jīng)是經(jīng)過(guò)Proguard優(yōu)化過(guò)的。經(jīng)過(guò)了Proguard對(duì)apk進(jìn)行壓縮,優(yōu)化,混淆后,在去對(duì)這個(gè)已經(jīng)進(jìn)行優(yōu)化過(guò)的apk進(jìn)行瘦身更有意義。下面是項(xiàng)目總常用的對(duì)apk進(jìn)行優(yōu)化的方式:在app的主module下的gradle文件中做如下配置buildTypes

{ release

{ //開(kāi)啟代碼混淆 minifyEnabled

true //Zipalign優(yōu)化 zipAlignEnabled

true //移除無(wú)用的resource文件 shrinkResources

true proguardFiles

getDefaultProguardFile('proguard-android.txt'),

'' }}使用shrinkResources進(jìn)行移除,配合//Zipalign優(yōu)化使用shrinkResources必須先開(kāi)啟代碼混淆minifyEnabled關(guān)于混淆相關(guān)的配置,不是本文重點(diǎn),下面進(jìn)行簡(jiǎn)單介紹proguard-android.txt文件中的常用的混淆配置信息如下:#

This

is

a

configuration

file

for

ProGuard.#

/index.html#manual/usage.html-dontusemixedcaseclassnames-dontskipnonpubliclibraryclasses-verbose#

Optimization

is

turned

off

by

default.

Dex

does

not

like

code

run#

through

the

ProGuard

optimize

and

preverify

steps

(and

performs

some#

of

these

optimizations

on

its

own).-dontoptimize-dontpreverify#

Note

that

if

you

want

to

enable

optimization,

you

cannot

just#

include

optimization

flags

in

your

own

project

configuration

file;#

instead

you

will

need

to

point

to

the#

"proguard-android-optimize.txt"

file

instead

of

this

one

from

your#

perties

file.-keepattributes

*Annotation*-keep

public

class

com.google.vending.licensing.ILicensingService-keep

public

class

com.android.vending.licensing.ILicensingService#

For

native

methods,

see

/manual/examples.html#native-keepclasseswithmembernames

class

*

{

native

<methods>;}#

keep

setters

in

Views

so

that

animations

can

still

work.#

see

/manual/examples.html#beans-keepclassmembers

public

class

*

extends

android.view.View

{

void

set*(***);

***

get*();}#

We

want

to

keep

methods

in

Activity

that

could

be

used

in

the

XML

attribute

onClick-keepclassmembers

class

*

extends

android.app.Activity

{

public

void

*(android.view.View);}#

For

enumeration

classes,

see

/manual/examples.html#enumerations-keepclassmembers

enum

*

{

public

static

**[]

values();

public

static

**

valueOf(java.lang.String);}-keepclassmembers

class

*

implements

android.os.Parcelable

{

public

static

final

android.os.Parcelable$Creator

CREATOR;}-keepclassmembers

class

**.R$*

{

public

static

<fields>;}#

The

support

library

contains

references

to

newer

platform

versions.#

Dont

warn

about

those

in

case

this

app

is

linking

against

an

older#

platform

version.

We

know

about

them,

and

they

are

safe.-dontwarn

android.support.**-dontusemixedcaseclassnames表示混淆時(shí)不使用大小寫混合類名。-dontskipnonpubliclibraryclasses表示不跳過(guò)library中的非public的類。-verbose表示打印混淆的詳細(xì)信息。-dontoptimize表示不進(jìn)行優(yōu)化,建議使用此選項(xiàng),因?yàn)楦鶕?jù)proguard-android-optimize.txt中的描述,優(yōu)化可能會(huì)造成一些潛在風(fēng)險(xiǎn),不能保證在所有版本的Dalvik上都正常運(yùn)行-dontpreverify表示不進(jìn)行預(yù)校驗(yàn)。這個(gè)預(yù)校驗(yàn)是作用在Java平臺(tái)上的,Android平臺(tái)上不需要這項(xiàng)功能,去掉之后還可以加快混淆速度。-keepattributesAnnotation表示對(duì)注解中的參數(shù)進(jìn)行保留。更多關(guān)于proguard混淆規(guī)則的介紹,請(qǐng)參考Android安全***戰(zhàn),反編譯與混淆技術(shù)完全解析(下)大部分應(yīng)用其實(shí)并不需要支持幾十種語(yǔ)言的國(guó)際化支持,比如國(guó)內(nèi)應(yīng)用只支持中文,配置如下:defaultConfig

{

...

//只保留指定和默認(rèn)的資源

//resConfigs('zh-rCN','ko')

resConfigs

"zh"}經(jīng)過(guò)上面的配置后,打包出的apk,在進(jìn)行apk的分析,這樣效果會(huì)更好。Androidstudio從2.2開(kāi)始就提供了分析apk文件的功能,在AndroidStudio工具欄里,打開(kāi)build–>AnalyzeAPK,選擇要分析的APK包,或者直接將apk包拖到AS中。下圖是對(duì)apk分析的結(jié)果:但是在看上面這個(gè)圖之前,需要先了解各個(gè)部分的含義:lib這個(gè)目錄存放應(yīng)用程序依賴的用C/C++編寫的native庫(kù)文件,該目錄下可以包含3種類型,根據(jù)CPU類型的不同加載不同目錄下的so庫(kù),這3種類型分別為ARM架構(gòu)、MIPS架構(gòu)、X86架構(gòu)。所示,不同的CPU架構(gòu)設(shè)備在應(yīng)用程序運(yùn)行時(shí),根據(jù)CPU架構(gòu)類型加載對(duì)應(yīng)的目錄,每個(gè)目錄可以存放很多對(duì)應(yīng)版本的so庫(kù),同時(shí)這個(gè)目錄結(jié)構(gòu)固定,用戶必須嚴(yán)格按照這個(gè)目錄存放自己的so文件。assetsassets目錄可以根據(jù)應(yīng)用需求存放任何文件夾架構(gòu),如配置文件、資源文件(如WebView本地資源、圖片資源等),這些文件的內(nèi)容在程序運(yùn)行過(guò)程中可以通過(guò)AssetManager類獲得。和res的不同點(diǎn)在于,res目錄下的文件會(huì)在.R文件中生成對(duì)應(yīng)的資源IDassets不會(huì)自動(dòng)生成對(duì)應(yīng)的ID,而是通過(guò)AssetManager類的接口獲取。resres是resource的縮寫,這個(gè)目錄存放資源文件,在這個(gè)文件夾下的所有文件都會(huì)生成對(duì)應(yīng)的ID映射到Android工程的.R文件中,訪問(wèn)時(shí)可以直接使用資源。classes.dexJava可執(zhí)行程序,需要先把Java文件編譯成class文件,字節(jié)碼都保存在class文件中,Java虛擬機(jī)可以通過(guò)解釋并執(zhí)行這些class文件。而Dalvik虛擬機(jī)在Java虛擬機(jī)進(jìn)行了優(yōu)化,執(zhí)行的是Dalvik字節(jié)碼,這些Dalvik字節(jié)碼由Java字節(jié)碼轉(zhuǎn)換而來(lái),一般情況下,Android應(yīng)用在打包時(shí)通過(guò)AndroidSDK中的dx工具將Java字節(jié)碼轉(zhuǎn)換為Dalvik字節(jié)碼。dx工具可以對(duì)多個(gè)class文件進(jìn)行合并重組、優(yōu)化,達(dá)到減小體積、縮短運(yùn)行時(shí)間的目的。META-INF保存應(yīng)用的簽名信息,簽名信息可以驗(yàn)證APK文件的完整性。AndroidSDK在打包APK時(shí)會(huì)計(jì)算APK包中所有文件的完整性,并且把這些完整性保存到META-INF文件夾下,應(yīng)用程序在安裝時(shí)首先根據(jù)META-INF文件夾校驗(yàn)APK的完整性,這樣可以保證APK中的每一個(gè)文件都不能被篡改。以此來(lái)確保APK應(yīng)用程序不被惡意修改或者病毒感染,有利于確保Android應(yīng)用的完整性和系統(tǒng)的安全性。META-INF目錄下包含的文件有CERT.RSA、CERT.DSA、CERT.SF和MANIFEST.MF,其中CERT.RSA是開(kāi)發(fā)者利用私鑰對(duì)APK進(jìn)行簽名的簽名文件,CERT.SF、MANIFEST.MF記錄了文件中文件的SHA-1哈希值。AndroidManifest.xmlAndroid應(yīng)用程序的配置文件是用來(lái)描述Android應(yīng)用“整體資訊”的設(shè)定文件,簡(jiǎn)單來(lái)說(shuō),相當(dāng)于Android應(yīng)用向Android系統(tǒng)“自我介紹”的配置文件。Android系統(tǒng)可以根據(jù)這個(gè)“自我介紹”完整地了解APK應(yīng)用程序的資訊,每個(gè)Android應(yīng)用程序都必須包含一個(gè)AndroidManifest.xml文件,且它的名字固定的,不能修改。在開(kāi)發(fā)Android應(yīng)用程序時(shí),一般都在AndroidManifest.xml中注冊(cè)代碼中的每個(gè)Activity、Service、Provider和Receiver,只有這樣系統(tǒng)才能啟動(dòng)對(duì)應(yīng)的組件,另外這個(gè)文件還包含一些權(quán)限聲明以及使用的SDK版本信息等。rsources.arsc記錄資源文件和資源ID之間的映射關(guān)系,用來(lái)根據(jù)資源ID尋找資源。Android的開(kāi)發(fā)是分模塊的,res目錄專門用來(lái)存放資源文件,在代碼中需要調(diào)用資源文件時(shí),只需要調(diào)用findviewbyId()就可以得到資源文件,每當(dāng)在res文件夾下放一個(gè)文件,aapt就會(huì)自動(dòng)生成對(duì)應(yīng)的ID保存在.R文件中,調(diào)用這個(gè)ID就可以,但是只有這個(gè)ID還不夠,.R文件只是保證編譯程序不報(bào)錯(cuò),實(shí)際上在程序運(yùn)行時(shí),系統(tǒng)要根據(jù)ID尋找對(duì)應(yīng)的資源路徑,而resources.arsc文件就是用來(lái)記錄這些ID和資源文件位置對(duì)應(yīng)關(guān)系的文件。通過(guò)上圖中對(duì)apk文件中各個(gè)部分的文件占比的分析,可以看到占用空間的主要是代碼、圖片、資源和lib和assert文件,主要方向精簡(jiǎn)代碼、壓縮圖片、去除無(wú)用的庫(kù)、減少asserts里面文件。so文件優(yōu)化首先對(duì)lib文件夾進(jìn)行瘦身:lib文件夾中存放的都是so文件,so文件存放到不同的cpu架構(gòu)的文件夾中,之所以這樣處理,就需要了解so的編譯類型,Android只支持3種cpu架構(gòu)分為:arm,mips,x86,目前用的最多的是arm體系cpu,x86和mips體系的很少用到了。arm體系中,又分32位和64位armeabi/armeabi-v7a:這個(gè)架構(gòu)是arm類型的,主要用于Android4.0之后的,cpu是32位的,其中armeabi是相當(dāng)老舊的一個(gè)版本,缺少對(duì)浮點(diǎn)數(shù)的硬件支持,基本已經(jīng)淘汰,可以不用考慮了。arm64-v8a:這個(gè)架構(gòu)是arm類型的,主要是用于Android5.0之后,cpu是64位的。平時(shí)項(xiàng)目中引入第三方的so文件時(shí),第三方會(huì)根據(jù)cpu的架構(gòu)編譯成不同類型的so文件,項(xiàng)目引入這些so文件時(shí),會(huì)將這些文件分別放入jniLibs目錄下的arm64-v8a,armeabi-v7a等這些目錄下,其實(shí)對(duì)于arm體系的so文件,沒(méi)這個(gè)必要,因?yàn)閍rm體系是向下兼容的,比如32位的so文件是可以在64位的系統(tǒng)上運(yùn)行的。Android上每啟動(dòng)一個(gè)app都會(huì)創(chuàng)建一個(gè)虛擬機(jī),Android64位的系統(tǒng)加載32位的so文件時(shí),會(huì)創(chuàng)建一個(gè)64位的虛擬機(jī)的同時(shí),還會(huì)創(chuàng)建一個(gè)32位的虛擬機(jī),這樣就能兼容32位的app應(yīng)用了。鑒于兼容的原理,在app中,可以只保留armeabi-v7a版本的so文件就足夠了。64位的操作系統(tǒng)會(huì)在32位的虛擬機(jī)上加載這個(gè)它。這樣就極大的精簡(jiǎn)了app打包后的體積。雖然這樣可以精簡(jiǎn)apk的體積,但是,在64位平臺(tái)上運(yùn)行32位版本的ART和Android組件,將丟失專為64位優(yōu)化過(guò)的性能(ART,webview,media等等)所以,更好的方法是,為相應(yīng)的abi打?qū)?yīng)的apk包,這樣就可以為不同abi版本生成不同的apk包。所以可以通過(guò)如下配置,只保留armeabi-v7a版本的so文件在module的build.gradle文件中defaultConfig節(jié)點(diǎn)做下面的配置:

``` //配置so庫(kù)架構(gòu)(真機(jī):

arm

,模擬器

x86

) defaultConfig

{

...

ndk

{

//abiFilters

"armeabi",

"armeabi-v7a"

abiFilters

'armeabi-v7a'

}

} ``` 完成這個(gè)步驟后,就可以看到,apk包中的lib中,只剩下armeabi-v7a文件夾中的so文件了。重新編譯so文件,用更小的庫(kù)代替很多第三方我們導(dǎo)入進(jìn)來(lái)只用到其中很小一部分功能,大部分功能都是我們用不上的。這時(shí)候我們找到源代碼,將我們需要的那部分代碼提取出來(lái),重新編譯成新的so文件,再導(dǎo)入到我們項(xiàng)目中。通過(guò)插件化,動(dòng)態(tài)加載so庫(kù)文件。assets目錄中的優(yōu)化如果存放的資源文件實(shí)在太大,可以考慮將部分不是立刻用到的資源文件,從網(wǎng)絡(luò)上下載到本地。這樣也能夠減少asstes目錄的大小。res目錄優(yōu)化:手動(dòng)lint檢查,手動(dòng)刪除無(wú)用的資源文件。版本迭代過(guò)程中,不但有廢棄代碼冗余,肯定會(huì)有無(wú)用的圖片存在。在build.gradle里面配置shrinkResourcestrue,在打包的時(shí)候會(huì)自動(dòng)清除掉無(wú)用的資源,但經(jīng)過(guò)實(shí)驗(yàn)發(fā)現(xiàn)打出的包并不會(huì),而是會(huì)把部分無(wú)用資源用更小的東西代替掉。注意,這里的“無(wú)用”是指調(diào)用圖片的所有父級(jí)函數(shù)最終是廢棄代碼,而shrinkResourcestrue只能去除沒(méi)有任何父函數(shù)調(diào)用的情況,真正起效果只能通過(guò)AndroidStudio自帶的“RemoveUnusedResources”小插件來(lái)實(shí)現(xiàn)了。更人性化是該查找結(jié)果可以“一鍵刪除”。當(dāng)然,可能圖片是經(jīng)過(guò)反射或字符拼接等方式獲取,所以這個(gè)檢測(cè)列表也不是全對(duì),刪除后很大概率編譯失敗或部分頁(yè)面掛死、無(wú)圖等問(wèn)題,這個(gè)無(wú)解,工具還沒(méi)智能到這個(gè)地步,你只能一遍又一遍“編譯—解決部分問(wèn)題—再編譯再”。使用tinypng等圖片壓縮工具對(duì)圖片進(jìn)行壓縮TinyPNG工具只支持上傳PNG圖片到官網(wǎng)上壓縮,然后下載保存,在保持alpha通道的情況下對(duì)PNG的壓縮可以達(dá)到1/3之內(nèi),而且用肉眼基本上分辨不出壓縮的損失.。Tinypng的官方網(wǎng)站:/大部分的圖片使用webp格式替代webp支持透明度,壓縮比比jpg更高但顯示效果卻不輸于jpg,官方評(píng)測(cè)quality參數(shù)等于75均衡最佳。相對(duì)于jpg、png,webp作為一種新的圖片格式,限于android的支持情況暫時(shí)還沒(méi)用在手機(jī)端廣泛應(yīng)用起來(lái)。從Android4.0+開(kāi)始原生支持,但是不支持包含透明度,直到Android4.2.1+才支持顯示含透明度的webp,使用的時(shí)候要特別注意。官方介紹:/speed/webp/docs/precompiled盡量少使用幀動(dòng)畫,幀動(dòng)畫需要的圖片較多,并且很占內(nèi)存,建議使用屬性動(dòng)畫替代。使用一套資源對(duì)于絕大對(duì)數(shù)APP來(lái)說(shuō),只需要取一套設(shè)計(jì)圖就足夠了。鑒于現(xiàn)在分辨率的趨勢(shì),建議取1080p的資源,放到xxhdpi目錄,在加上一些屏幕適配的處理,基本能夠適配大部分的手機(jī)。相對(duì)于多套資源,只使用1080P的一套資源,在視覺(jué)上差別不大,很多大公司的產(chǎn)品也是如此,但卻能顯著的減少資源占用大小,順便也能減輕設(shè)計(jì)師的出圖工作量了。使用jpg格式如果對(duì)于非透明的大圖,jpg將會(huì)比png的大小有顯著的優(yōu)勢(shì),雖然不是絕對(duì)的,但是通常會(huì)減小到一半都不止。在啟動(dòng)頁(yè),活動(dòng)頁(yè)等之類的大圖展示區(qū)采用jpg將是非常明智的選擇??s小大圖如果經(jīng)過(guò)上述步驟之后,你的工程里面還有一些大圖,考慮是否有必要維持這樣的大尺寸,是否能適當(dāng)?shù)目s小。事實(shí)上,由于設(shè)計(jì)師出圖的原因,我們拿到的很多圖片完全可以適當(dāng)?shù)目s小而對(duì)視覺(jué)影響是極小的。覆蓋第三庫(kù)里的大圖有些第三庫(kù)里引用了一些大圖但是實(shí)際上并不會(huì)被我們用到,就可以考慮用1x1的透明圖片覆蓋。你可能會(huì)有點(diǎn)不舒服,因?yàn)槟愕膁rawable下竟然包含了一些莫名其妙的名稱的1x1圖片使用微信資源壓縮打包工具(AndResGuard)矢量圖矢量圖是由點(diǎn)與線組成,和位圖不一樣,它再放大也能保持清晰度,而且使用矢量圖比位圖設(shè)計(jì)方案能節(jié)約30~40%的空間,現(xiàn)在谷歌一直在強(qiáng)調(diào)扁平化方式,矢量圖可很好的契合該設(shè)計(jì)理念。優(yōu)勢(shì)(1)占用存儲(chǔ)空間小(2)無(wú)極拉伸不會(huì)出現(xiàn)鋸齒,可以照顧不同尺寸的機(jī)型(3)AndroidStudio自帶很多資源,減小UI工作量劣勢(shì)(1)只支持5.0及以上系統(tǒng)(2)與位圖相比多了一層計(jì)算,需消耗更多性能(3)不支持.9圖(4)不適合表現(xiàn)真實(shí)照片和復(fù)雜圖形,一般使用在簡(jiǎn)單的icon和動(dòng)畫上

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論