天天看點

Android APP編譯流程

Android Gradle plugin的具體流程

  • 首先上一張官方的圖:
    Android APP編譯流程
  1. 首先通過aapt打包res資源檔案,生成R.java、resources.arsc和res檔案(二進制&非二進制保持原來的代碼)
  2. 處理.aidl檔案,生成對應的Java接口檔案
  3. 通過Java Compile編譯R.java、java接口檔案,生成.class檔案
  4. 通過dex指令,将.class檔案和第三方庫中的.class檔案處理生成classes.dex檔案
  5. 通過apkbuilder将aapt生成的CompiledResources和其他資源檔案以及classes.dex檔案打包生成apk
  6. 通過Jarsigner工具,對上面的apk進行debug或者release簽名
  7. 通過zipalign工具,将簽名後的apk進行對齊處理
  • 建構流程圖:
    Android APP編譯流程

    1.編譯器将源代碼轉換成dex檔案(包括Android裝置上的位元組碼),将所有的其他内容轉換成已編譯資源

    2.APK打包器将DEX檔案和已編譯資源合成單個APK,不過,必須先簽署APK,才能将應用安裝并部署到Android裝置上

    3.APK打包器使用調試或釋出密鑰簽署庫簽署APK(分為debug和release版本)

    4.在生成最終的APK之前,打包器會使用zipalign工具對應用進行優化,減少其在裝置上運作時的記憶體占用

建構

  • 主要使用的android gradle plugin是com.androi.application 和com.android.library,兩者對應的類分别是com.android.build.gradle.AppPlugin,而com.android.library插件對應的類是com.android.build.gradle.LibraryPlugin
  • 函數執行流程
apply()->configureProject()->configureExtension()->createTasks()->createAndroidTasks()
           

Gradle生命周期

  • 初始化階段,執行settings.gradle,并将每個Project内的build.gradle轉化為project對象
  • Configration階段,配置對應的Project對象,執行build.gradle中的代碼,Configuration階段完結後,整個build的project以及内部的Task關系就确定了,Configuration會建立一個有向圖來描述Task之間的依賴關系
  • 執行階段:執行相應的task
  • 每個生命周期都可以進行hook
  • 可以在 setting中設定不同的gradle,本地和遠端用不同的也可以引入不同的moudle
  • 可以在build.gradle中定義各種變體,可以設定使用本地moudle或者使用遠端的moudle
  • 可以在任意的Task前插入自己的Task, 編譯時增删java代碼,修改位元組碼等,各種插件,hook代碼都是在這裡進行執行的,還可以制作子產品熱插拔,優化編譯速度等

R檔案引用到真正的資源檔案

  • aapt工具對于每個資源檔案生成了位移的ID,這些ID儲存在R.java檔案中
//資源ID是一個4位元組表示的無符号整數,在R.java檔案中用16進制表示,其中,最高的1位元組表示Package ID, 次高1個位元組表示TypeID, 最低2位元組表示Entry ID
public final class R {
    public static final class anim {
        public static final int abc_fade_in=0x7f050000;
        public static final int abc_fade_out=0x7f050001;
        public static final int abc_grow_fade_in_from_bottom=0x7f050002;
      
    }
    public static final class animator {
        public static final int design_appbar_state_list_animator=0x7f060000;
        public static final int slide_in_left=0x7f060001;
        public static final int slide_out_left=0x7f060002;
    }
           
  • aapt在生成ID的同時還生成了一個resources.arsc檔案,相當于一個資源索引表,該表的key是資源ID, value是資源在apk中的路徑
  • 是以通過R.java和resources.arsc檔案就可以引用到實際的資源檔案

對齊優化

  • 在上面的打包過程中涉及到對齊這個詞,在編譯原理中學到過記憶體對齊,在這裡如果每個資源的開始位置都是上一個資源之後的4 * n位元組,那麼通路下一個資源就不需要周遊,直接跳至4* n位元組處并判斷資源的時間戳即可(數組的随機通路比連結清單快)

繼續閱讀