apk結構分析以及減小包大小

個人csdn:hanking.blog.csdn.net/css

前言

apk的大小對於下載apk應用的用戶多少有直接的影響,因爲手機內存的限制和網絡環境的限制,同一個應用隨着apk越大下載的和使用的人數就會越少,因此減小apk的大小是很是重要的。本文從apk編譯過程,apk的組成,apk大小減小的方法三個方面分析如何減小apk的大小html

一、apk的編譯過程

在構建過程當中,Android項目會被編譯,打包,生成.apk文件,apk文件包含了運行的所有必要信息。主要包括: 一、.dex文件java

二、AndroidManifest.xml文件linux

三、編譯的資源文件resources.arscandroid

四、未編譯的資源文件安全

Android編譯打包簡單流程圖

網絡

在這裏插入圖片描述
上面的流程圖中簡單的歸納了Android編譯和打包過程,Android項目編譯和打包生成apk文件,apk文件簽名後,使用adb工具安裝在Android device或者emulator上就能夠運行了。

Android 具體的build過程

.apk文件要經過打包過程當中許多工具生成中間文件最終生成的。app

apk打包工具jvm

在這裏插入圖片描述
由上圖看出Android 構建過程當中包括的構建工具備:

aapt(The Android Asset Packaging Tool ):aapt Android中的資源打包工具,主要是用於處理Android項目中的資源文件好比xml,drawable,等文件。ide

Java compiler: java編譯器,編譯java文件生成.class文件。

dex: dex生成器,dex會把class轉化爲Dalvik byte code,也會把第三方的源碼編譯進.dex文件中。

apkbuilder: apk生成器,編譯過的資源文件和未編譯的資源文件以及dex文件還有其餘文件經過apk builder生成apk文件

jarsigner: 簽名器,.apk文件經過簽名後生成signed.apk文件,簽名後的apk就能夠安裝和運行了。

apk的build流程圖

在這裏插入圖片描述
上面的流程圖能夠很清晰的看到打包整個打包的過程:

一、資源打包過程

首先項目中資源文件經過aapt資源打包工具生成R.java文件,和編譯過的資源文件resources.arsc,R.java文件中存放的是各個資源的id,在java代碼中經過R文件中的id來找到對應的資源。resources.arsc中放的是編譯過的資源文件相關的信息:好比xml文件的節點(LinearLayout, RelativeLayout)佈局的屬性( android:layout_width)資源的id。下圖是資源打包更具體的流程:

在這裏插入圖片描述
二、class文件生成

資源打包過程當中生成的R.java文件中包含了資源的id,java代碼中經過這些id能夠尋找到相關的資源。R.java類和項目中其餘java源碼,以及aidl接口經過java compiler生成.class文件。

在這裏插入圖片描述
三、dex文件生成

上面項目源碼中生成的class文件和第三方庫經過dex生成.dex文件,Android運行在Dalvik Virtual Machine上,和Java不一樣,Java運行在jvm上,Dalvik Virtual Machine上運行的不是.class文件,而是.dex文件。 可使用android-sdk中的dexdump 工具來反編譯dex文件。dexer工具能夠把class文件轉換成.dex文件。

在這裏插入圖片描述

dex的優勢 dexer打包工具會消除class文件中的冗餘信息,全部的class文件會被打包進同一個dex文件中,使用dex會很大的減小apk的大小,下面表格是使用dex工具後文件的大小對比:

在這裏插入圖片描述
由上表可知使用dex文件能夠極大的減小應用的大小。

二、apk結構

在這裏插入圖片描述

由上圖能夠看出apk主要由META-INF,assets,res,lib,resources.arsc,classes.dex,AndroidManifest.xml,等8個部分組成,下面分別對這個8個組成進行分析。 一、META-INF apk其實是一個包含了各類結構信息的jar文件,META-INF文件夾包含了manifest信息和jar的包信息META-INF主要包括下圖的三個部分組成:

在這裏插入圖片描述

一、MANIFEST.MF:包含導入jar運行時的信息,包括運行時啓動哪一個main class。package的版本號,build number。package的建立者信息,安全和容許證書信息等。

二、CERT.SF: 包含全部文件列表信息以及文件的SHA-1摘要。

三、CERT.RSA: 包含CERT.SF文件的簽名內容以及用於對該內容簽名的公鑰證書。

一個簡單的META-INF文件

Manifest-Version: 1.0
Created-By: 1.7.0_60 (Oracle Corporation)

Name: res/drawable-xxhdpi-v4/common_plus_signin_btn_text_dark_pressed.9.png
SHA1-Digest: Db3E0/I85K9Aik2yJ4X1dDP3Wq0=

Name: res/drawable-xhdpi-v4/opt_more_item_close_press.9.png
SHA1-Digest: Xxm9cr4gDbEEnnYvxRWfzcIXBEM=

Name: res/anim/accessibility_guide_translate_out.xml
SHA1-Digest: dp8PyrXMy2IBxgTz19x7DATpqz8=
複製代碼

二、RES

res會在R.java生成索引ID,在打包的時候判斷資源有沒有用到,沒用到的時候不會被打包進apk中(res/raw文件夾除外), res用getResource()訪問,res/raw裏的文件在打包的時候不會被系統二進制編譯,都被原封不動打包進APK,一般用來存放遊戲資源、腳本、字體文件等,res/xml會被編譯成二進制文件。res/anim存放動畫資源。

在這裏插入圖片描述
注意:res中的資源不會被編譯進 resources.arsc中。

assets和res的區別

在這裏插入圖片描述

三、resources.arsc

Android編譯過程當中Android的資源打包工具(Android Asset Packaging Tool)aapt,會生成一個R.java文件,這個文件保存layout,styles,等資源的惟一id。而且生成一個resources.arsc文件,這個文件中保存了資源的屬性信息好比: 一、xml文件的節點(LinearLayout, RelativeLayout) 二、佈局的屬性( android:layout_width) 三、資源的id resources.arsc中的信息會在運行的時候被解析。

三、減小apk大小

由上面知道了apk的組成,可知要減小apk的大小就是要減小上面apk組成中的各個模塊的大小,減少包大小的方法以下圖所示:

在這裏插入圖片描述

減小資源數目移除無用資源

一、使用lint工具進行檢測

res/layout/preferences.xml: Warning: The resource R.layout.preferences appears
    to be unused [UnusedResources]
複製代碼

注意lint不會檢測asset文件夾中的文件

二、使用shrinkResources

若是若是在 app的build.gradle 文件中配置shrinkResources屬性,gradle會自動移除無用資源

android {
    // Other settings

    buildTypes {
        release {
            minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } 複製代碼

進行了上面的配置後在build的過程當中,ProGuard會先移除無用的代碼可是不會移除無用的資源,Gradle會移除無用的資源。

減小動畫幀

幀動畫因爲每一幀都是一幅圖片因此很是容易增長apk的大小,減小幀數可以很是有效的減小apk大小。下面是一個幀率爲30的動畫包含的圖片,

在這裏插入圖片描述
包含了接近30張圖片,若是把幀數換成15,圖片數目會減小一半。

使用xml定義純色圖片

有些圖片並不須要靜態的圖片資源,對於一些純色的圖片儘可能使用用shape,color的xml文件來代替圖片,使用xml定義的shape可以有效的減小apk大小。

複用圖片資源

在開發中有些圖片只是顏色不同,有些圖片只是大小不同,有些圖片只是角度不同。Android提供了相應的方法來複用這些圖片。

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_arrow_expand"
    android:fromDegrees="180"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toDegrees="180" />

複製代碼

壓縮圖片

Android Asset Packaging Tool Android Asset Packaging Tool簡稱aapt,AAPT 可以查看,建立,更新,zip文件,而且可以將資源編譯成二進制文件,是Android sdk中自帶的打包class和resource工具。

The Android Asset Packaging Tool (aapt) takes your application resource files, such as the AndroidManifest.xml file and the XML files for your Activities, and compiles them。

可以在:..\android-sdk\build-tools\<buildToolsVersion>包中找到。

aapt命令的使用

  • 建立apks (Android application bundles)
aapt package, aapt add 
複製代碼
  • aapt dump 查看apk的信息: 一、查看版本號:
aapt dump badging name.apk
複製代碼

二、查看權限:

aapt dump permissions name.apk
複製代碼

使用aapt工具對圖片進行壓縮,aapt工具在build過程當中能對res/drawable/文件夾下的文件進行無損壓縮。

aapt的缺點 一、aapt不會壓縮 asset/文件夾下的png圖片 二、 三、aapt不會過濾已經壓縮過的圖片,因此會對已經壓縮過的圖片形成影響,爲了不這種影響能夠在gradle中使用

aaptOptions {
    cruncherEnabled = false
}
複製代碼

減小使用枚舉

一個枚舉類會形成class.dex增大1.0到1.4kb大小。 If possible, consider using the @IntDef annotation and ProGuard to strip enumerations out and convert them to integers. This type conversion preserves all of the type safety benefits of enums

參考文獻

一、stackoverflow.com/questions/6…

二、stackoverflow.com/questions/2…

三、developer.android.com/guide/topic…

四、developer.android.com/reference/a…

五、developer.android.com/guide/topic…

六、stackoverflow.com/questions/2…

七、elinux.org/Android_aap…

八、developer.android.com/guide/topic… 九、stackoverflow.com/questions/3… 十、stackoverflow.com/questions/5… 十一、stackoverflow.com/questions/1…

十二、stuff.mit.edu/afs/sipb/pr…

1三、medium.com/@kevalpatel…

1四、stackoverflow.com/questions/7…

1五、source.android.com/devices/tec…

相關文章
相關標籤/搜索