Android FrameWork学习(一)Android 7 0系统源码下载 编译
最近計(jì)劃著研究下 Android 7.0 的系統(tǒng)源碼,之前也沒(méi)做過(guò)什么記錄,這次正好將學(xué)習(xí)的內(nèi)容記錄下來(lái),方便以后復(fù)習(xí)鞏固。
既然要學(xué)習(xí)我們的系統(tǒng)源碼,那我們第一步要做的就是下載源碼并進(jìn)行編譯了。
#硬件環(huán)境要求
###1. 編譯環(huán)境 按照官方的說(shuō)法,編譯 Android 2.3.x 及以上版本的系統(tǒng)源碼需要 64 位的系統(tǒng)運(yùn)行環(huán)境來(lái)支持,而編譯 2.3.x 以下的版本則需要 32 位的系統(tǒng)運(yùn)行環(huán)境。
###2. 硬盤(pán)空間 官方建議最好預(yù)留 100G 的磁盤(pán)空間來(lái)下載源碼,150G 的磁盤(pán)空間用來(lái)編譯源碼,如果使用了 ccache(一個(gè)高速編譯緩存工具,可以大幅加快 gcc 的編譯速度),那么則需要更大的空間來(lái)支持。
所以盡可能地保證自己的磁盤(pán)空間夠大吧,之前就因?yàn)榇疟P(pán)空間預(yù)留不夠?qū)е略创a編譯過(guò)程中空間不足,狠狠地把自己坑了一把。
###3. 內(nèi)存空間 如果你是在虛擬機(jī)上跑 linux,官方建議至少需要 16G 的內(nèi)存空間,我的機(jī)器只有 8G 的內(nèi)存空間跑虛擬機(jī),目前跑起來(lái)也沒(méi)太大問(wèn)題,就是編譯源碼的過(guò)程非常漫長(zhǎng),不知道是否跟內(nèi)存大小有關(guān)。
#軟件環(huán)境要求 ###1. 操作系統(tǒng)
Android 系統(tǒng)的源碼的編譯支持 Linux 跟 Mac OS 兩種操作系統(tǒng),一般情況下,Android 系統(tǒng)源碼都是在 Linux Ubuntu 系統(tǒng)上進(jìn)行開(kāi)發(fā)與測(cè)試的,所以如果你準(zhǔn)備使用 Linux 系統(tǒng)來(lái)進(jìn)行源碼編譯,那一般推薦安裝 Ubuntu 版本的 Linux。
下面列出了各 Android 版本與編譯系統(tǒng)版本的對(duì)應(yīng)關(guān)系
Linux:
| Android 6.0 (Marshmallow) - Android最新版本 | Ubuntu 14.04 (Trusty) |
| Android 2.3.x (Gingerbread) - Android 5.x (Lollipop) | Ubuntu 12.04 (Precise) |
| Android 1.5 (Cupcake) - Android 2.2.x (Froyo) | Ubuntu 10.04 (Lucid) |
Mac OS
| Android 6.0 (Marshmallow) - Android最新版本 | Mac OS v10.10 (Yosemite) or later with Xcode 4.5.2 and Command Line Tools |
| Android 5.x (Lollipop) | Mac OS v10.8 (Mountain Lion) with Xcode 4.5.2 and Command Line Tools |
| Android 4.1.x-4.3.x (Jelly Bean) - Android 4.4.x (KitKat) | Mac OS v10.6 (Snow Leopard) or Mac OS X v10.7 (Lion) and Xcode 4.2 (Apple's Developer Tools) |
| Android 1.5 (Cupcake) - Android 4.0.x (Ice Cream Sandwich) | Mac OS v10.5 (Leopard) or Mac OS X v10.6 (Snow Leopard) and the Mac OS X v10.5 SDK |
###2.JDK 版本要求 不同的Android版本編譯也需要對(duì)應(yīng)的 JDK 環(huán)境,這里列出了各版本之間的對(duì)應(yīng)關(guān)系
|Android 版本|JDK 版本(Ubuntu)|JDK 版本(Mac OS)| |---|---| |Android 目前最新版本|?OpenJDK 8| jdk 8u45 or newer| |Android 5.x (Lollipop) - Android 6.0 (Marshmallow)|OpenJDK 7|jdk-7u71-macosx-x64.dmg| |Android 2.3.x (Gingerbread) - Android 4.4.x (KitKat)|Java JDK 6|Java JDK 6| |Android 1.5 (Cupcake) - Android 2.2.x (Froyo)|Java JDK 5| ?|
#搭建編譯環(huán)境
根據(jù)上面列出的軟硬件要求,我們可以根據(jù)自己要編譯的 Android 版本以及自己的設(shè)備來(lái)選擇合適的系統(tǒng)及JDK,接下來(lái)我們就來(lái)說(shuō)說(shuō)如何搭建編譯環(huán)境。
這里我們主要針對(duì)Android 7.0的需要的編譯環(huán)境分別對(duì) Linux 和 Mac OS 進(jìn)行配置:
###設(shè)置 Linux 系統(tǒng)編譯環(huán)境 ####1.安裝 JDK
Android 7.0目前需要 openJDK 8的 JDK 環(huán)境
#####Ubuntu 15.04+ 如果你的系統(tǒng)是 Ubuntu 15.04 及以上版本的話,直接運(yùn)行如下指令即可直接安裝:
$ sudo apt-get update $ sudo apt-get install openjdk-8-jdk 復(fù)制代碼#####Ubuntu 14.04 如果你使用的是 Ubuntu 14.04 版本,現(xiàn)在并沒(méi)有專門(mén)針對(duì)14.0.4可用的 open jdk8 的包,
但是 Ubuntu 15.04 OpenJDK 8 的包可以在 14.0.4 上成功地運(yùn)行,所以我們下載 Ubuntu 15.04 OpenJDK 8 的安裝包來(lái)手動(dòng)安裝:
從?archive.ubuntu.com上依次下載下面列出的64位的 open JDK 8 的.deb安裝包 openjdk-8-jre-headless_8u45-b14-1_amd64.deb? openjdk-8-jre_8u45-b14-1_amd64.deb openjdk-8-jdk_8u45-b14-1_amd64.deb
安裝 .deb 包 先運(yùn)行 apt-get 指令更新軟件列表
接著依次對(duì)上面下載的三個(gè) deb 文件運(yùn)行如下指令進(jìn)行安裝:
sudo dpkg -i 下載的文件地址 復(fù)制代碼最后運(yùn)行 apt-get -f 指令修復(fù)安裝依賴的包
sudo apt-get -f install 復(fù)制代碼####2.安裝所需要的工具包
#####Ubuntu 14.04
我們編譯過(guò)程中會(huì)用到下面的依賴包,執(zhí)行如下指令統(tǒng)一安裝:
sudo apt-get install git-core gnupg flex bison gperf build-essential \zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 \lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache \libgl1-mesa-dev libxml2-utils xsltproc unzip 復(fù)制代碼####3.設(shè)置源碼編譯輸出路徑 默認(rèn)情況下,編譯好的系統(tǒng)源碼會(huì)在源碼所在目錄的out文件夾下, 如果你希望調(diào)整輸出目錄的路徑,可以執(zhí)行下面的指令指定輸出目錄:
export OUT_DIR_COMMON_BASE=<path-to-your-out-directory> 復(fù)制代碼####4.設(shè)置 USB 接口訪問(wèn)設(shè)備 在linux下,默認(rèn)情況是不允許普通用戶直接通過(guò) USB 接口來(lái)訪問(wèn)設(shè)備的.
推薦方法是以根用戶身份在 /etc/udev/rules.d/51-android.rules 路徑創(chuàng)建文件。
我們可以通過(guò)如下指令來(lái)實(shí)現(xiàn)(注意用你的系統(tǒng)username替換指令中的):
wget -S -O - http://source.android.com/source/51-android.rules | sed "s/<username>/$USER/" | sudo tee >/dev/null /etc/udev/rules.d/51-android.rules; sudo udevadm control --reload-rules 復(fù)制代碼###設(shè)置 Mac OS 系統(tǒng)編譯環(huán)境 Mac OS 的文件系統(tǒng)默認(rèn)情況下保留了大小寫(xiě)實(shí)際上卻又不區(qū)分大小寫(xiě)。 目前的git指令無(wú)法支持這樣的文件系統(tǒng),會(huì)導(dǎo)致一些莫名其妙的錯(cuò)誤,所以在 Mac OS 上編譯 Android 系統(tǒng)源碼,我們必須先創(chuàng)建一塊區(qū)分大小寫(xiě)的磁盤(pán)鏡像。
####創(chuàng)建一塊區(qū)分大小寫(xiě)的磁盤(pán)鏡像 這里我們直接通過(guò)命令行來(lái)創(chuàng)建:
hdiutil create -type SPARSE -fs 'Case-sensitive Journaled HFS+' -size 40g ~/android.dmg 復(fù)制代碼該指令會(huì)在系統(tǒng)根目錄下生成一個(gè) android.dmg 或是 android.dmg.sparseimage 文件,一旦掛載,將被作為支持 Android 開(kāi)發(fā)所需格式的驅(qū)動(dòng)鏡像分區(qū)。
如果之后你需要更大的空間,你可以通過(guò)下面的指令進(jìn)行空間調(diào)整:
hdiutil resize -size <new-size-you-want>g ~/android.dmg.sparseimage 復(fù)制代碼你還可以在 ~/.bash_profile 文件中,添加幫助函數(shù)來(lái)掛載跟取消掛載:
# mount the android file image function mountAndroid { hdiutil attach ~/android.dmg -mountpoint /Volumes/android; }#如果創(chuàng)建dmg文件時(shí)生成的是android.dmg.sparseimage文件,則使用 function mountAndroid { hdiutil attach ~/android.dmg.sparseimage -mountpoint /Volumes/android; } 復(fù)制代碼# unmount the android file image function umountAndroid() { hdiutil detach /Volumes/android; } 復(fù)制代碼之后我們就可以通過(guò)執(zhí)行 mountAndroid 指令來(lái)執(zhí)行掛載鏡像,通過(guò) umountAndroid 指令來(lái)取消掛載。
####安裝 JDK #####安裝工具依賴包 ######1. 安裝 xcode 命令行工具
$ xcode-select --install 復(fù)制代碼對(duì)于老版本的 Mac OS 系統(tǒng)(10.8或者10.8之前的),我們需要到蘋(píng)果開(kāi)發(fā)者站點(diǎn)進(jìn)行下載安裝. 如果你還沒(méi)有注冊(cè)成為蘋(píng)果開(kāi)發(fā)者,你需要先注冊(cè)一個(gè)蘋(píng)果賬號(hào)來(lái)進(jìn)行下載.
######2. 到 macports.org 上下載對(duì)應(yīng)Mac OS版本的 macports (類似于Linux下的 apt-get,用來(lái)幫助你安裝其他應(yīng)用程序)
注意:確保 /opt/local/bin 在路徑 /usr/bin 前,如果沒(méi)有,在 ~/.bash_profile 文件中進(jìn)行添加
export PATH=/opt/local/bin:$PATH 復(fù)制代碼注意:如果根目錄下沒(méi)有 .bash_profile 文件,那就手動(dòng)創(chuàng)建一個(gè)
#####3. 通過(guò) macports 安裝 make , git 以及 GPG
$ POSIXLY_CORRECT=1 sudo port install gmake libsdl git gnupg 復(fù)制代碼如果使用的是 Mac OS X v10.4 版本的系統(tǒng),還需要安裝 bison :
$ POSIXLY_CORRECT=1 sudo port install bison 復(fù)制代碼注意:如果是編譯 Android 4.0.x 及以下版本的系統(tǒng),gmake 3.8.2 版本存在一個(gè) bug,需要還原到 gmake 3.8.1
###優(yōu)化編譯環(huán)境(可選)
####設(shè)置 ccache
我們可以自由選擇是否開(kāi)啟 ccache 編譯工具。
ccache 是一個(gè)高速編譯緩存工具,它通過(guò)將頭文件高速緩存到源文件之中而改進(jìn)了構(gòu)建性能,因而通過(guò)減少每一步編譯時(shí)添加頭文件所需要的時(shí)間而提高了 C\C++ 的構(gòu)建速度。
從編譯的全過(guò)程來(lái)看,不使用 ccache 的情況下,編譯過(guò)程中會(huì)多次解析相同的頭文件,浪費(fèi)了處理器周期,更重要的是浪費(fèi)了開(kāi)發(fā)者的時(shí)間,因?yàn)樗麄円却@一過(guò)程的完成。在一個(gè)團(tuán)隊(duì)中,這一影響可能會(huì)更為明顯,因?yàn)閳F(tuán)隊(duì)成員可能會(huì)反復(fù)編譯解析相同的頭文件。
所以,一般對(duì)于專門(mén)用來(lái)編譯系統(tǒng)的服務(wù)器或是大容量的生產(chǎn)環(huán)境,這個(gè)功能比較有用,它可以加速重新編譯的速度。
注意:如果你只是個(gè)人開(kāi)發(fā)者,不是專門(mén)的編譯服務(wù)器,不需要進(jìn)行增量構(gòu)建的話,那么使用 ccache 可能會(huì)因?yàn)楦咚倬彺嫒笔Ф档湍愕臉?gòu)建速度。
####開(kāi)啟 ccache 要開(kāi)啟 ccache,在源碼樹(shù)的根路徑下執(zhí)行下面的指令:
$ export USE_CCACHE=1 $ export CCACHE_DIR=/<path_of_your_choice>/.ccache $ prebuilts/misc/linux-x86/ccache/ccache -M 50G 復(fù)制代碼緩存的大小一般設(shè)置為50G-100G
接著在 .bashrc (或者 etc/profile )中添加下面的指令
export USE_CCACHE=1 復(fù)制代碼默認(rèn)情況下,緩存會(huì)存在home根目錄的 ~/.ccache 中,但是如果你使用的是NFS或者其他的非本地文件系統(tǒng),那么你同樣需要在 .bashrc 指定緩存目錄地址
在 Mac OS 的系統(tǒng)中,你需要將 linux-x86 替換成 darwin-x86:
prebuilts/misc/darwin-x86/ccache/ccache -M 50G 復(fù)制代碼當(dāng)編譯的 Android 系統(tǒng)是4.0.x或者更老的版本,ccache 的緩存路徑會(huì)有所不同
prebuilt/linux-x86/ccache/ccache -M 50G 復(fù)制代碼這個(gè)設(shè)置會(huì)一直存儲(chǔ)在 CCACHE_DIR 中。
在Linux上,你可以通過(guò)以下指令開(kāi)啟對(duì) ccache 的監(jiān)聽(tīng):
$ watch -n1 -d prebuilts/misc/linux-x86/ccache/ccache -s 復(fù)制代碼#下載源碼 編譯環(huán)境配置好之后,我們就可以開(kāi)始下載我們的源碼了
###安裝 Repo Repo 是 google 用 python 寫(xiě)的一個(gè)腳本工具,Android 使用 git 作為代碼管理工具,一個(gè) Android 系統(tǒng)由 N 多個(gè) git 庫(kù)構(gòu)成,如果手動(dòng)進(jìn)行一個(gè)個(gè)下載,那簡(jiǎn)直是一件非常痛苦的事,而 repo 就是用來(lái)對(duì)這些 git 庫(kù)進(jìn)行維護(hù)管理跟下載的。
通過(guò) Repo 工具,我們可以輕松地完成 Android 系統(tǒng)源碼的下載。
#####1.在系統(tǒng) home 根路徑下創(chuàng)建bin目錄并且添加到 path 路徑中:
#創(chuàng)建bin目錄 $ mkdir ~/bin#把bin目錄的路徑添加到PATH中 $ PATH=~/bin:$PATH 復(fù)制代碼#####2.下載 repo 工具并設(shè)置其可執(zhí)行
#curl 是個(gè)開(kāi)源文件傳輸工具,在這里是把遠(yuǎn)程的 repo 文件下載到指定的 ~/bin/repo 路徑 $ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo#修改 repo 對(duì)所有人可執(zhí)行 $ chmod a+x ~/bin/repo 復(fù)制代碼###初始化 Repo 客戶端
######1.創(chuàng)建一個(gè)空目錄用來(lái)存放我們的 Android 系統(tǒng)源碼,名字自己隨便定
#創(chuàng)建名為 WORKING_DIRECTORY 的目錄 $ mkdir WORKING_DIRECTORY#進(jìn)入到創(chuàng)建的目錄中 $ cd WORKING_DIRECTORY 復(fù)制代碼######2.初始化 repo 倉(cāng)庫(kù)
從主干 master 下載源碼,目前最新版本
$ repo init -u https://android.googlesource.com/platform/manifest 復(fù)制代碼如果需要下載某個(gè)特定版本系統(tǒng)的分支,可以在上述命令后加 -b 版本分支號(hào),這里我指定 Android 7.0 的版本分支
$ repo init -u https://android.googlesource.com/platform/manifest -b android-7.1.0_r7 復(fù)制代碼具體的版本分支號(hào)可以到這個(gè)地址查看(需要翻墻): Android系統(tǒng)個(gè)版本分支號(hào)
######3.同步源碼到本地 這時(shí)執(zhí)行 sync 指令便可以自動(dòng)下載源碼到本地了
$ repo sync 復(fù)制代碼###使用國(guó)內(nèi)鏡像下載源碼 由于國(guó)內(nèi)網(wǎng)絡(luò)的問(wèn)題,上述操作的源碼下載需要翻墻才能進(jìn)行,速度會(huì)受到很大影響,幾十G的系統(tǒng)源碼可能需要花上上周的時(shí)間才能下完,
因此我們可以選擇國(guó)內(nèi)的鏡像進(jìn)行源碼下載:
清華大學(xué)的鏡像站 參照頁(yè)面上的描述對(duì)上面的指令稍作調(diào)整便可以了,站點(diǎn)上寫(xiě)得比較詳細(xì),這里我們就不作贅述了。
根據(jù)網(wǎng)速的不同,一般一天之內(nèi)能夠下載完畢。
對(duì)于下載下來(lái)的源碼,我們并不能直接刷到我們的目標(biāo)設(shè)備上或者是使用模擬器運(yùn)行,我們必須對(duì)源碼進(jìn)行編譯生成對(duì)應(yīng)的 image 二進(jìn)制鏡像文件, 當(dāng)然你也可以直接從官網(wǎng)下載對(duì)應(yīng)系統(tǒng)版本的鏡像文件(需翻墻): ?Google's Nexus driver page Binaries Preview for Nexus Devices
這里我們還是自己來(lái)編譯下源碼,熟悉下整個(gè)編譯過(guò)程。
#源碼編譯
首先我們通過(guò)命令行進(jìn)入到源碼目錄中,我這里目錄的名稱是aosp
cd aosp 復(fù)制代碼###清空輸出目錄 為了確保我們編譯生成的文件不受之前 build 構(gòu)建的文件影響,我們?cè)谠创a目錄中執(zhí)行下面的指令,該指令會(huì)清空 out 輸出目錄中的所有文件
$ make clobber 復(fù)制代碼###設(shè)置編譯環(huán)境 首先我們通過(guò)源碼 build 目錄中的 envsetup.sh 腳本文件初始化我們的編譯環(huán)境,執(zhí)行
$ source build/envsetup.sh 復(fù)制代碼或
$ . build/envsetup.sh 復(fù)制代碼這兩個(gè)指令的效果是一樣的,會(huì)初始化一些有用的命令工具
我們后面執(zhí)行的一些指令必須在初始化 envsetup之后才能執(zhí)行
###選擇編譯目標(biāo)
接著我們通過(guò) lunch 指令來(lái)選擇我們需要編譯的目標(biāo) 執(zhí)行l(wèi)unch指令
$ lunch 復(fù)制代碼會(huì)彈出可選目標(biāo)項(xiàng):
所有的構(gòu)建目標(biāo)由 BUILD-BUILDTYPE 的形式組成: BUILD 對(duì)應(yīng) codename
這是官方提供的一份對(duì)照表:
|Device| Code name| Build configuration |---|---| |Pixel XL |marlin |aosp_marlin-userdebug| |Pixel|sailfish |aosp_sailfish-userdebug| |HiKey| hikey| hikey-userdebug| |Nexus 6P| angler |aosp_angler-userdebug| |Nexus 5X |bullhead |aosp_bullhead-userdebug| |Nexus 6 |shamu |aosp_shamu-userdebug| |Nexus Player |fugu| aosp_fugu-userdebug| |Nexus 9 |volantis (flounder) |aosp_flounder-userdebug| |Nexus 5 (GSM/LTE) |hammerhead |aosp_hammerhead-userdebug| |Nexus 7 (Wi-Fi) |razor (flo) |aosp_flo-userdebug| |Nexus 7 (Mobile) |razorg (deb) |aosp_deb-userdebug| |Nexus 10 |mantaray (manta) |full_manta-userdebug| |Nexus 4 |occam (mako) |full_mako-userdebug| |Nexus 7 (Wi-Fi) |nakasi (grouper)| full_grouper-userdebug| |Nexus 7 (Mobile)| nakasig (tilapia)| full_tilapia-userdebug| |Galaxy Nexus (GSM/HSPA+)| yakju (maguro)| full_maguro-userdebug| |Galaxy Nexus (Verizon) |mysid (toro) |aosp_toro-userdebug| |Galaxy Nexus (Experimental) |mysidspr (toroplus) |aosp_toroplus-userdebug| |Motorola Xoom (U.S. Wi-Fi) |wingray |full_wingray-userdebug| |Nexus S| soju (crespo)| full_crespo-userdebug| |Nexus S 4G |sojus (crespo4g) |full_crespo4g-userdebug|
BUILD_TYPE 對(duì)照表:
| user | 有限的訪問(wèn)權(quán)限,主要用于發(fā)布正式產(chǎn)品,沒(méi)有 root 跟調(diào)試權(quán)限 |
| userdebug | 跟 user 類型差不多,但是多了 root 跟 debug 調(diào)試權(quán)限 |
| eng | 擁有各種調(diào)試工具的開(kāi)發(fā)版設(shè)置,擁有 root 跟 debug 權(quán)限 |
如果作為開(kāi)發(fā)使用的話,那我們一般都是選 -eng,
這里我自己是準(zhǔn)備在模擬器上運(yùn)行編譯的 image 鏡像,并且我電腦的 cpu 是 intel x86 的,所以我選擇了 6. aosp_x86-eng
我們可以根據(jù)自己的需要選擇對(duì)應(yīng)的 cpu 類型。
注意:我們知道,Android 官方的模擬器速度很慢, Intel 特意提供了一個(gè)叫 HAXM 的虛擬硬件加速技術(shù),全稱為:Intel Hardware Accelerated Execution Manager.
只要你的 CPU 是 intel 的產(chǎn)品并且支持 VT(virtualization Technology)就可以使用 HAXM 技術(shù)將你的模擬器的速度提升至真機(jī)的水平。
目前 Intel 只提供了 windows 版和 MAC 版,Linux 系統(tǒng)只有通過(guò)安裝 KVM 來(lái)達(dá)到這個(gè)效果。
#####安裝 KVM 首先我們檢測(cè)下自己的 cpu 是否支持 hardware virtualization(硬件虛擬化)
egrep -c '(vmx|svm)' /proc/cpuinfo 復(fù)制代碼輸出的值如果是大于 0 的,則表明你的 cpu 支持
如果你使用的是 vmware 虛擬機(jī)安裝的 linux,注意要設(shè)置下虛擬機(jī)的 cpu 來(lái)支持硬件虛擬化,先關(guān)閉虛擬機(jī),然后右鍵虛擬機(jī)=》設(shè)置,選中 cpu,勾選虛擬化 Intel VT 項(xiàng),這樣就能支持 KVM 了。
對(duì)于 Ubuntu 10.0.4 以上的版本,我們通過(guò)下面的指令安裝 KVM 即可
sudo apt-get install qemu-kvm libvirt-bin ubuntu-vm-builder bridge-utils 復(fù)制代碼如果在安裝 KVM 的過(guò)程中有什么疑問(wèn)的話,可以訪問(wèn)下面這個(gè)網(wǎng)址查找方法:https://help.ubuntu.com/community/KVM/Installation
這樣,在編譯完目標(biāo) intel cpu 的鏡像文件后,我們運(yùn)行模擬器就會(huì)自動(dòng)進(jìn)行加速了。
#編譯源碼 好了,一切就緒,我們可以開(kāi)始編譯我們的源碼了, 我們?cè)谠创a路徑下通過(guò) make -jN 指令來(lái)進(jìn)行源碼編譯,這里的 N 一般建議設(shè)置為 cpu 核心線程數(shù)的 1-2 倍。
$ make -j4 復(fù)制代碼一般情況下,我們等待源碼編譯完成就可以了,不過(guò)從 Android 7.0 N 開(kāi)始,make 指令默認(rèn)會(huì)開(kāi)啟 Jack 編譯工具鏈來(lái)進(jìn)行 Java 代碼的編譯,這個(gè)過(guò)程中可能會(huì)出現(xiàn)一些問(wèn)題。
#####什么是 Jack 編譯工具鏈 (The Jack toolchain)? 我們知道,我們平時(shí)編譯 Android 代碼的時(shí)候會(huì)先將 Java 代碼編譯成 .class 文件,最終再轉(zhuǎn)換成 .dex 文件,如圖:
而 Jack 編譯工具鏈則跳過(guò)了編譯成 .class 文件這一過(guò)程,直接將 Java 代碼編譯成 .dex文件
它的優(yōu)勢(shì):
- 完全開(kāi)放源碼 源碼均在 AOSP 中,合作伙伴可貢獻(xiàn)源碼
- 加快編譯源碼 Jack 提供特殊的配置,減少編譯時(shí)間:pre-dexing ,增量編譯和Jack編譯服務(wù)器.
- 支持代碼壓縮,混淆,重打包和 multidex
- 不在使用額外單獨(dú)的包,例如 ProGuard。
如果想進(jìn)一步了解 Jack,可以訪問(wèn)Compiling with Jack(需翻墻),這里就不作太多解釋了。
按照官方的說(shuō)法 Jack 可以加快編譯速度
但實(shí)際編譯過(guò)程中,在我的設(shè)備上 Jack 會(huì)占用大量?jī)?nèi)存,并且拖慢編譯速度,還會(huì)報(bào)錯(cuò),而且官方文檔上寫(xiě)的配置方式對(duì) Jack 并不起作用。
#####Jack編譯過(guò)程中遇到的問(wèn)題 ######編譯過(guò)程中報(bào) Out of memory error 并中斷編譯 在執(zhí)行 make 指令后,當(dāng)?shù)谝淮尉幾g Java 代碼的時(shí)候,Jack 會(huì)被啟用,這個(gè)時(shí)候經(jīng)常會(huì)卡住,并且一段時(shí)間后報(bào)錯(cuò) Out of memory error 。
按照官方的說(shuō)法, Jack 并行編譯的時(shí)候占用的資源太大導(dǎo)致內(nèi)存溢出了
可以通過(guò)在 $HOME/.jack 文件中減小 SERVER_NB_COMPILE 的值來(lái)減小并行編譯數(shù)量, SERVER_NB_COMPILE 的值默認(rèn)為4
但實(shí)際情況是 Jack 沒(méi)有在根路徑下生成 .jack 文件,并且手動(dòng)創(chuàng)建設(shè)置 SERVER_NB_COMPILE 后重啟 Jack 服務(wù)也沒(méi)有效果。
經(jīng)測(cè)試發(fā)現(xiàn) make 編譯過(guò)程中當(dāng) Jack 第一次被啟用時(shí)會(huì)在 home 根路徑下生成 .jack-server 目錄
可以通過(guò)修改該目錄中 config.properties 文件里的.jack.server.max-service值來(lái)設(shè)置并發(fā)線程數(shù)。
同時(shí),你也可以設(shè)置增加 Jack 的內(nèi)存容量來(lái)解決這個(gè)問(wèn)題,指令如下
export JACK_SERVER_VM_ARGUMENTS="-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx4096m" 復(fù)制代碼然后進(jìn)入到輸出路徑的 bin 目錄下:
cd /home/cjpx00008/aosp/out/host/linux-x86/bin 復(fù)制代碼執(zhí)行下面的指令重啟 Jack 服務(wù)
./jack-admin stop-server./jack-admin start-server 復(fù)制代碼我改了 service 大小,同時(shí)增加了內(nèi)存,后來(lái)編譯的過(guò)程中沒(méi)有發(fā)生其他問(wèn)題。
#####有辦法關(guān)閉 Jack 編譯嗎? 既然Jack有問(wèn)題,那我們可以關(guān)閉 Jack 編譯嗎?
目前來(lái)說(shuō)我還沒(méi)有找到如何在 Android 7.0 編譯的時(shí)候關(guān)閉 Jack,如果有知道的小伙伴歡迎留言告訴我哈,感激不盡!!
#運(yùn)行編譯出的 image 鏡像
經(jīng)過(guò)漫長(zhǎng)的等待,我們的源碼終于編譯結(jié)束了,是時(shí)候來(lái)運(yùn)行編譯出的 image 鏡像了。
這時(shí)我們只要在源碼目錄下執(zhí)行 emulator 指令即可運(yùn)行模擬器
$ emulator 復(fù)制代碼第一次啟動(dòng)時(shí)間可能會(huì)有點(diǎn)長(zhǎng),耐心等待即可
運(yùn)行成功了,是不是有點(diǎn)小激動(dòng)呢!
注意:如果你的命令行窗口關(guān)閉重開(kāi)了,那 emulator 指令可能會(huì)提示找不到命令,我們可以在源碼根目錄環(huán)境下,通過(guò) envsetup.sh 重新初始化命令,運(yùn)行 lunch 指令選擇編譯目標(biāo),這個(gè)時(shí)候你再運(yùn)行 emulator 就不會(huì)提示找不到指令了(每次關(guān)閉命令行窗口都需要重新運(yùn)行如下指令才能執(zhí)行 emulator)
也可以通過(guò)配置環(huán)境變量來(lái)設(shè)置 emulator 指令,不過(guò)我沒(méi)有成功,哈哈
$ source build/envsetup.sh $ lunch $ emulator 復(fù)制代碼好啦,到此,我們的源碼就編譯完畢啦,下一篇我們來(lái)聊聊如何使用 Android Studio 導(dǎo)入 Android 系統(tǒng)源碼,并通過(guò) AS 進(jìn)行 Java 源碼調(diào)試,以及使用 GDB 來(lái)調(diào)試系統(tǒng) Native C\C++ 源碼。
總結(jié)
以上是生活随笔為你收集整理的Android FrameWork学习(一)Android 7 0系统源码下载 编译的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Android 4 +https(如何启
- 下一篇: 老司机带你重构Android的v4包的部