Android Studio 的 build 過程

 

如圖,html

  • 編譯器源代碼(包括 Application Module 及其所依賴的全部 Library 源代碼)轉換成 DEXDalvik Executable)文件(其中包括運行在 Android 設備上的字節碼),將全部其餘內容轉換成已編譯資源。(
    • 源代碼(包括 Application Module 和 Library Module)編譯成 class 文件,再將全部的 class 文件(包括第三方庫中)打包生成 dex 文件。
    • 解壓全部 aar 包中的資源文件,並和項目中全部資源文件合併到一個目錄。
    • 生成資源文件的索引文件。
  • APK 打包器DEX 文件和已編譯資源打包生成單個 APK。不過,必須先對 APK 簽名,才能將應用安裝並部署到 Android 設備上。
  • APK 打包器使用 Debug 或 Release 密鑰庫對 APK 簽名
    • 若是您構建的是 Debug 版本的應用(即專用於測試和分析的應用),打包器會使用 Debug 密鑰庫簽名應用。Android Studio 自動使用 Debug 密鑰庫配置新項目。
    • 若是您構建的是打算向外發佈的 Release 版本應用,打包器會使用 Release 密鑰庫簽名應用。
  • 在生成最終 APK 以前,打包器會使用 zipalign 工具對應用進行優化減小其在設備上運行時的內存佔用

 

2. Gradle 構建 tasks 說明

咱們經過 Android Studio 的 build -> Build APK 功能來看下, build 過程當中是怎樣的。 Build APK 會執行如下 Gradle task。 ( 注:這裏是用 Debug 模式作例子, Release 模式時只需將 task 中的 Debug 替換成 Release 理解便可)

Executing tasks: [:app:assembleDebug]

:app:preBuild UP-TO-DATE
:app:preDebugBuild UP-TO-DATE
:app:compileDebugAidl UP-TO-DATE
:app:compileDebugRenderscript UP-TO-DATE
:app:generateDebugResValues UP-TO-DATE
:app:generateDebugResources UP-TO-DATE
:app:mergeDebugResources UP-TO-DATE
:app:transformDataBindingBaseClassLogWithDataBindingMergeGenClassesForDebug UP-TO-DATE
:app:dataBindingGenBaseClassesDebug UP-TO-DATE
:app:checkDebugManifest UP-TO-DATE
:app:generateDebugBuildConfig UP-TO-DATE
:app:prepareLintJar UP-TO-DATE
:app:mainApkListPersistenceDebug UP-TO-DATE
:app:createDebugCompatibleScreenManifests UP-TO-DATE
:app:processDebugManifest
:app:splitsDiscoveryTaskDebug UP-TO-DATE
:app:processDebugResources
:app:generateDebugSources
:app:dataBindingExportBuildInfoDebug
:app:javaPreCompileDebug UP-TO-DATE
:app:transformDataBindingWithDataBindingMergeArtifactsForDebug UP-TO-DATE
:app:compileDebugJavaWithJavac
:app:compileDebugNdk NO-SOURCE
:app:compileDebugSources
:app:mergeDebugShaders UP-TO-DATE
:app:compileDebugShaders UP-TO-DATE
:app:generateDebugAssets UP-TO-DATE
:app:mergeDebugAssets UP-TO-DATE
:app:transformClassesWithDexBuilderForDebug
:app:transformDexArchiveWithExternalLibsDexMergerForDebug
:app:transformDexArchiveWithDexMergerForDebug
:app:mergeDebugJniLibFolders UP-TO-DATE
:app:transformNativeLibsWithMergeJniLibsForDebug UP-TO-DATE
:app:processDebugJavaRes NO-SOURCE
:app:transformResourcesWithMergeJavaResForDebug UP-TO-DATE
:app:validateSigningDebug UP-TO-DATE
:app:packageDebug
:app:assembleDebug


BUILD SUCCESSFUL in 20s
特別說明:因爲 Gradle 會嘗試經過不重複執行輸入未發生變化的 task 來節省時間(這些 task 被標記爲 UP-TO-DATE,如上所示)
因此第一次編譯運行會比較久,然後面就不會了。

  

上面列出來的 Gradle 構建過程,大體可分爲五個階段java

  1. Preparation of dependecies 在這個階段 Gradle 檢測 Module 依賴的全部 library 是否 ready。若是這個 Module 依賴於另外一個 Module ,則另外一個 Module 也要被編譯。
  2. Merging resources and processing Manifest 打包資源Manifest 文件。
  3. Compiling 在這個階段處理編譯器的註解源碼被編譯成字節碼
  4. Postprocessing 全部帶 transform 前綴的 task 都是這個階段進行處理的。
  5. Packaging and publishing 這個階段 library 生成.aar文件,Application 生成.apk文件。

這五個階段和上面的構建過程當中 task 的時序有大體的對應關係,你們能夠相互映照着理解。android

爲了便於你們理解,下面給出一些關鍵 task 的說明:git

  • mergeDebugResources 解壓全部的 aar 包輸出到app/build/intermediates/exploded-aar,而且把全部的資源文件合併到app/build/intermediates/res/merged/debug目錄裏。github

  • processDebugManifest 把全部 aar 包裏的AndroidManifest.xml中的節點,合併到項目的AndroidManifest.xml中,並根據app/build.gradle中當前buildType 的 manifestPlaceholders配置內容替換 manifest 文件中的佔位符,最後輸出到app/build/intermediates/manifests/full/debug/AndroidManifest.xmlapi

  • processDebugResourcesapp

    1. 調用 aapt 生成項目和全部 aar 依賴的R.java,輸出到app/build/generated/source/r/debug目錄;
    2. 生成資源索引文件app/build/intermediates/res/debug/resources-debug.ap_
    3. 符號表輸出到app/build/intermediates/symbols/debug/R.txt
  • compileDebugJavaWithJavac 用來把 java 文件編譯成 class 文件,輸出的路徑是app/build/intermediates/classes/debugide

    編譯的輸入目錄有工具

    • 項目源碼目錄,默認路徑是app/src/main/java,能夠經過 sourceSetsdsl 配置,容許有多個(打印project.android.sourceSets.main.java.srcDirs能夠查看當前全部的源碼路徑,具體配置能夠參考 android-doc,以及這裏
    • app/build/generated/source/aidl
    • app/build/generated/source/buildConfig
    • app/build/generated/source/apt(繼承javax.annotation.processing.AbstractProcessor作動態代碼生成的一些庫,輸出在這個目錄)的代碼。
  • transformClassesWithMultidexlistForDebug這個任務在使用 Multidex 纔會出現)它有兩個做用測試

    • 掃描項目的AndroidManifest.xml文件和分析類之間的依賴關係,計算出那些類必須放在第一個 dex 裏面,最後把分析的結果寫到app/build/intermediates/multi-dex/debug/maindexlist.txt文件裏面
    • 生成混淆配置項輸出到app/build/intermediates/multi-dex/debug/manifest_keep.txt文件裏

    項目裏的代碼入口是 manifestapplication 節點的屬性 android.name 配置的繼承自 Application 的類,在 Android 5.0 之前的版本系統只會加載一個 dex(classes.dex),classes2.dex .......classesN.dex 通常是使用android.support.multidex.MultiDex加載的,因此若是入口的 Application 類不在 classes.dex5.0 如下確定會掛掉,另外當入口 Application 依賴的類不在 classes.dex 時初始化的時候也會由於類找不到而掛掉,還有若是混淆的時候類名變掉了也會由於對應不了而掛掉,綜上所述就是這個任務的做用。

相關文章
相關標籤/搜索