【朝花夕拾】Android性能篇之(四)Apk打包

前言html

        轉載請聲明,轉自【http://www.javashuo.com/article/p-wlbnlznl-gm.html】,謝謝!java

        APK,即Android Package,是將android程序和資源整合在一塊兒,造成的一個.apk文件。相信全部的Android程序員是在IDE的幫助下,完成打包垂手可得,但對打包流程真正清楚的可能並很少。本章的內容比較簡單,也是很是基礎的內容,可是對理解android應用的結構卻有很大的幫助。筆者寫這篇文章的目的,一方面是爲了彌補這方面的盲點,回顧和梳理apk打包方面的理論知識點;第二方面,是爲了給後續寫Android虛擬機知識作鋪墊,進而去研究android的性能優化,這也是把這篇文章放到Android性能優化系列文章當中的緣由;第三方面,也是爲了方便讀者理解Android虛擬機的相關內容。android

       對於在IDE,如Android Studio上操做打包的過程,本文不作演示,對於更深刻的源碼分析,也不在本文討論之列,出於前面說到的緣由,本文只簡單闡述其打包流程,本文主要內容以下:程序員

         

 

1、apk構建流程圖segmentfault

     如下截圖爲Google官方提供的詳細的apk構建過程圖,其中包含了各個環節所用到的工具和中間相關的文件。數組

                

                         apk構建過程(綠色部分爲對應環節工具,藍色部分爲相關文件)性能優化

 

2、構建過程當中所用工具app

        以下截圖展現了apk構建過程當中所使用的部分工具,這些工具大部分都在sdk/build-tools/文件夾下:工具

                 

                  

                    代碼混淆所用工具源碼分析

                 

                                   打包所用工具所在的jar包

3、apk打包流程詳解

       依據如上的流程圖和工具圖,下面我們按照流程順序對其進行講解。

  一、aapt打包資源

  • 工具:aapt(Android Asset Package Tool Android資源打包工具)
  • 工具路徑:sdkpath/build-tools/版本號/aapt.exe和aapt2.exe
  • 輸入:Android資源文件、AndroidManifest.xml
  • 輸出: R.java類、二進制的resource.arsc,res文件夾(包括二進制的xml、沒被改變的圖片和res/raw文件)、二進制的AndroidManifest.xml文件、沒有改變的assets文件夾。

        Android的資源文件包含了兩類:1)assets類資源。該類資源放在工程目錄的assets根目錄下,存放一些原始文件,這些文件不會被編譯爲二進制文件,而是被原封不動地打包在apk文件中,一樣也不能經過資源ID來查找,不保存在R文件中。2)res類資源,10種目錄。這類資源保存在工程目錄中的res目錄下,包含了animator(屬性動畫資源)、anim(補間動畫資源)、color(對象顏色狀態選擇資源)、drawable(xml或Bitmap文件的圖像資源)、layout(佈局文件資源)、menu(程序菜單資源)、mipmap(圖標資源,推薦閱讀:drawable與mipmap的區別)、raw(不被編譯成二進制文件的資源,注意和assets資源的區別,推薦閱讀:assets和raw的區別)、values(6種不一樣的值:數組arrays.xml、顏色值colors.xml、尺寸dimens.xml、字符串strings.xml和樣式值styles.xml)、xml(描述應用程序配置信息的資源)。

       以下截圖展現了R.java的內容,其中包含了各類靜態內部類,分別對應了某種資源的類型。

       

                            R.java結構圖

      以R.string類爲例,其中展現了字符串名稱對應的id值,就是對應在res/values文件夾下,string字符串資源。

      

                                                                    R.string結構圖

        推薦閱讀:apk打包安裝過程

  二、aidl生成跨進程通訊的java文件

  • 工具:aidl(Android Interface Definition Language安卓接口定義語言)
  • 工具路徑:sdkpath/build-tools/版本號/aidl.exe
  • 輸入:aidl後綴的文件,位於工程項目src/main/aidl目錄下
  • 輸出:可用於進程間通訊的C/S端java代碼,位於build/generated/source/aidl

          

                                       工程項目中的aidl原始文件

          

                                       aidl工具處理後生成的java文件

  三、Java編譯源碼

  • 工具:javac.exe
  • 工具路徑:jdk/bin/javac.exe
  • 輸入:java source文件夾、aapt中生成的R.java文件、aidl生成的java文件、BuildConfig.java文件
  • 輸出:對於gradle編譯,生成的class文件保存在build/intermediates/classes裏

         

                               BuildConfig.java和R.java文件

         

                                              輸出的class文件

  四、proguard代碼混淆

        完成javac編譯以後,通常還會對其進行代碼的混淆,其實就是相似於加密的功能,做用就是增長反編譯的難度,同時也將一些代碼的命名進行了縮短,減小代碼佔用的空間。推薦閱讀:Android代碼混淆零基礎入門

  • 工具:ProGuard
  • 工具路徑:sdk/tools/proguard/bin/proguard.bat
  • 輸入:被編譯過的class文件、混淆配置文件proguard-rules.pro
  • 輸出:被混淆過的.class文件、混淆先後映射文件

         

  五、將全部.class文件轉化爲classes.dex文件

  • 工具:dx.bat
  • 工具路徑:sdkpath/build-tools/版本號/dx.bat
  • 輸入:編譯後生成的全部.class文件、第三方庫和.class文件
  • 輸出:能夠在Android虛擬機上使用的.dex文件

       調用dx.bat將全部的class文件轉化爲classes.dex文件,將二進制碼轉化爲Android虛擬機(Android4.4之前虛擬機是Dalvik,4.4上是Dalvik和ART能夠切換、Android5.0及之後是ART)上的字節碼、生成常量池、消除冗餘數據等。因爲Android虛擬機是一種針對嵌入式設備而特殊設計的java虛擬機,全部dex文件與標準的class文件在結構設計上有着很大的區別,當javac將java程序編譯成class後,dx工具將全部的class文件整合到一個dex文件中,這樣作使得各個類可以共享數據,在必定程度上下降了容易,同時也使文結構更加緊湊,實驗代表,dex文件時傳統jar文件的50%左右。class文件結構和dex文件結構比對以下(該部分還會在後文講Android虛擬機時提到):

           

                     .class文件和.dex文件結構對比圖

  六、apkbuilder打包生成apk

  • 工具:ApkBuilder類
  • 工具路徑:sdkpath/tools/lib/sdklib_xxx.jar
  • 輸入:上一步生成的classes.dex文件,aapt時生成的resources.arsc、被編譯後的res文件夾、AndroidManifest.xml,Other Resouces(assets文件夾)
  • 輸出:.apk文件(Android Package)

  七、對apk進行簽名

  • 工具:apksigner.bat
  • 工具路徑:sdkpath/build-tools/版本號/apksigner.bat
  • 輸入:上一步中生成的.apk文件、簽名文件(Debug or Release Keystore)
  • 輸出:簽名後的.apk文件

      簽名是一個apk身份的證實,Android系統在安裝apk的時候,首先會檢驗apk的簽名,若是發現簽名文件不存在或者校驗簽名失敗,就會拒絕安裝。對一個apk文件簽名後,apk文件根目錄下回增長META-INF目錄,該目錄下有三個文件:

        

               META-IINF文件夾結構

      Android系統就是根據這三個文件的內容對apk文件進行簽名驗證的:

      MANIFEST.MF中包含對apk中除了/META-INF文件夾外全部文件的簽名值。

      

                                                 MANIFEST.MF內容截圖

      CERT.SF是對MANIFEST.MF文件總體簽名以及其中各個條目的簽名。通常地,若是是使用工具簽名,還多包括一項,就是對MANIFEST.MF頭部信息簽名。

      

                                                               CERT.SF內容截圖

      CERT.RSA包含用私鑰對CERT.SF的簽名以及包含公鑰信息的數字證書。用通常的文本打開後,會顯示亂碼。

      

                          CETR.RSA內容截圖

      推薦閱讀:Android簽名有什麼用?

                      Android簽名過程詳解

  八、zipalign優化

      若是是在release mode下,還會對apk進行align,即對簽名後的apk進行對齊處理,這種方式是對apk進行整理和優化。

  • 工具:zipalign
  • 工具路徑:sdkpath/build-tools/版本號/zipalign.exe
  • 輸入:上一步中籤名後的apk文件
  • 輸出:優化後的apk文件

 

4、APK文件結構

      一個apk解壓後,其典型的結構以下所示,分別在apk打包流程中appt資源打包、javac編譯、簽名階段所產生:

      

相關文章
相關標籤/搜索