Android Studio 的 build 过程
我們知道,在 Android 項目的開發過程中,只需要點一下 Android Studio 的運行按鈕,就可以將代碼編譯好并運行在設備上。相信任何一個 Android開發者都知道,從我們點擊按鈕到設備上運行 APP,Android Studio 默默地做了編譯、打包(生成 APK 文件)、安裝、運行等很多事情,安裝和運行不是本文所關心的內容。下面,我們一起來看看,Android Studio 的編譯、打包(也可以合并稱為構建)過程。
構建流程
先來看下 Android 官網給出的構建流程圖:
如圖 1 所示,典型 Android 應用模塊的構建流程通常依循下列步驟:
- 如果您構建的是 Debug 版本的應用(即專用于測試和分析的應用),`打包器`會使用 Debug 密鑰庫簽名應用。Android Studio 自動使用 Debug 密鑰庫配置新項目。
- 如果您構建的是打算向外發布的 Release 版本應用,`打包器`會使用 Release 密鑰庫簽名應用。
構建流程結束后,得到可用來進行部署、測試的 Debug APK,或者可用來發布給外部用戶的 Release APK。
本段內容參考 Android 官網(需科學上網,不能科學上網的童鞋點這里)
上面 Android 官方只是給出了 Android 大致的構建流程,并沒有詳細,下面通過實際構建來看一下,Android Studio 的 build 過程。
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 構建過程,大致可分為五個階段:
這五個階段和上面的構建過程中 task 的時序有大致的對應關系,大家可以相互映照著理解。
為了便于大家理解,下面給出一些關鍵 task 的說明:
mergeDebugResources 解壓所有的 aar 包輸出到app/build/intermediates/exploded-aar,并且把所有的資源文件合并到app/build/intermediates/res/merged/debug目錄里。
processDebugManifest 把所有 aar 包里的AndroidManifest.xml中的節點,合并到項目的AndroidManifest.xml中,并根據app/build.gradle中當前buildType 的 manifestPlaceholders配置內容替換 manifest 文件中的占位符,最后輸出到app/build/intermediates/manifests/full/debug/AndroidManifest.xml。
processDebugResources
- 調用 aapt 生成項目和所有 aar 依賴的R.java,輸出到app/build/generated/source/r/debug目錄;
- 生成資源索引文件app/build/intermediates/res/debug/resources-debug.ap_;
- 把符號表輸出到app/build/intermediates/symbols/debug/R.txt。
compileDebugJavaWithJavac 用來把 java 文件編譯成 class 文件,輸出的路徑是app/build/intermediates/classes/debug
編譯的輸入目錄有
- 項目源碼目錄,默認路徑是app/src/main/java,可以通過 sourceSets 的 dsl 配置,允許有多個(打印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文件里
項目里的代碼入口是 manifest 中 application 節點的屬性 android.name 配置的繼承自 Application 的類,在 Android 5.0 以前的版本系統只會加載一個 dex(classes.dex),classes2.dex …….classesN.dex 一般是使用android.support.multidex.MultiDex加載的,所以如果入口的 Application 類不在 classes.dex 里 5.0 以下肯定會掛掉,另外當入口 Application 依賴的類不在 classes.dex 時初始化的時候也會因為類找不到而掛掉,還有如果混淆的時候類名變掉了也會因為對應不了而掛掉,綜上所述就是這個任務的作用。
總結
簡而言之,Android Studio 的構建構成總結為以下幾點:
- 將源代碼(包括 Application Module 和 Library Module)編譯成 class 文件,再將所有的 class 文件(包括第三方庫中)打包生成 dex 文件。
- 解壓所有 aar 包中的資源文件,并和項目中所有資源文件合并到一個目錄。
- 生成資源文件的索引文件。
- 最終將所有的dex文件和已編譯的資源文件,打包生成.apk文件。
到這里,大家再次對照上面的流程圖,聯合理解,相信會有一種明悟的趕腳?
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的Android Studio 的 build 过程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 详解vue-router基本使用
- 下一篇: android sina oauth2.