這是很久以前訪問掘金的時候 無意間看到的一個關於Android的文章,作者更細心,分階段的將學習步驟記錄在自己博客中,我覺得很有用,想作為分享同時也是留下自己知識的一些欠缺收藏起來,今后做項目的時候會用到。
好了,廢話不多說了。直接來吧。。
Android 7.0系統源碼下載\編譯:http://blog.csdn.net/cjpx00008/article/details/67185045(這個鏈接並不是下載地址,而是對安卓系統編碼的一個闡述,源碼官網可以下載的)
這是Android 7.0系統源碼下載\編譯
原文
最近計划着研究下Android 7.0的系統源碼,之前也沒做過什么記錄,這次正好將學習的內容記錄下來,方便以后復習鞏固。
既然要學習我們的系統源碼,那我們第一步要做的就是下載源碼並進行編譯了。
硬件環境要求
1. 編譯環境
按照官方的說法,編譯Android 2.3.x及以上版本的系統源碼需要64位的系統運行環境來支持,而編譯2.3.x以下的版本則需要32位的系統運行環境。
2. 硬盤空間
官方建議最好預留100G的磁盤空間來下載源碼,150G的磁盤空間用來編譯源碼,如果使用了ccache(一個高速編譯緩存工具,可以大幅加快gcc的編譯速度),那么則需要更大的空間來支持。
所以盡可能地保證自己的磁盤空間夠大吧,之前就因為磁盤空間預留不夠導致源碼編譯過程中空間不足,狠狠地把自己坑了一把。
3. 內存空間
如果你是在虛擬機上跑Linux,官方建議至少需要16G的內存空間,我的機器只有8G的內存空間跑虛擬機,目前跑起來也沒太大問題,就是編譯源碼的過程非常漫長,不知道是否跟內存大小有關。
軟件環境要求
1. 操作系統
Android系統的源碼的編譯支持Linux跟Mac OS兩種操作系統,一般情況下,Android系統源碼都是在Linux Ubuntu系統上進行開發與測試的,所以如果你准備使用Linux系統來進行源碼編譯,那一般推薦安裝Ubuntu版本的Linux。
下面列出了各Android版本與編譯系統版本的對應關系
Linux:
Android版本 | GNU/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版本 | Mac OS (Intel/x86) |
---|---|
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版本編譯也需要對應的JDK環境,這里列出了各版本之間的對應關系
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 |
搭建編譯環境
據上面列出的軟硬件要求,我們可以根據自己要編譯的Android版本以及自己的設備來選擇合適的系統及JDK,接下來我們就來說說如何搭建編譯環境。
這里我們主要針對Android 7.0的需要的編譯環境分別對Linux和Mac OS進行配置:
設置Linux系統編譯環境
1.安裝JDK
Android 7.0目前需要openJDK 8的JDK環境
Ubuntu 15.04+
如果你的系統是Ubuntu 15.04及以上版本的話,直接運行如下指令即可直接安裝:
Ubuntu 14.04
如果你使用的是Ubuntu 14.04版本,現在並沒有專門針對14.0.4可用的open jdk8的包,
但是Ubuntu 15.04 OpenJDK 8的包可以在14.0.4上成功地運行,所以我們下載Ubuntu 15.04 OpenJDK 8的安裝包來手動安裝:
-
從 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包
先運行apt-get指令更新軟件列表
sudo apt-get update
接着依次對上面下載的三個deb文件運行如下指令進行安裝:
sudo dpkg -i 下載的文件地址
最后運行 apt-get -f 指令修復安裝依賴的包
sudo apt-get -f install
-
更新系統默認使用的JDK版本
如果你的系統安裝了多個版本的JDK,可以通過下面的指令執行切換,會彈出可選的JDK版本,根據你的需要選擇對應的版本就可以了:
2.安裝所需要的工具包
Ubuntu 14.04
我們編譯過程中會用到下面的依賴包,執行如下指令統一安裝:
3.設置源碼編譯輸出路徑
默認情況下,編譯好的系統源碼會在源碼所在目錄的out文件夾下,
如果你希望調整輸出目錄的路徑,可以執行下面的指令指定輸出目錄:
4.設置USB接口訪問設備
在linux下,默認情況是不允許普通用戶直接通過USB接口來訪問設備的.
推薦方法是以根用戶身份在 /etc/udev/rules.d/51-android.rules
路徑創建文件。
我們可以通過如下指令來實現(注意用你的系統username替換指令中的):
設置Mac OS系統編譯環境
Mac OS的文件系統默認情況下保留了大小寫實際上卻又不區分大小寫。
目前的Git指令無法支持這樣的文件系統,會導致一些莫名其妙的錯誤,所以在Mac OS上編譯Android系統源碼,我們必須先創建一塊區分大小寫的磁盤鏡像。
創建一塊區分大小寫的磁盤鏡像
這里我們直接通過命令行來創建:
該指令會在系統根目錄下生成一個android.dmg或是android.dmg.sparseimage文件,一旦掛載,將被作為支持Android開發所需格式的驅動鏡像分區。
如果之后你需要更大的空間,你可以通過下面的指令進行空間調整:
你還可以在 ~/.bash_profile
文件中,添加幫助函數來掛載跟取消掛載:
之后我們就可以通過執行mountAndroid指令來執行掛載鏡像,通過umountAndroid指令來取消掛載。
安裝JDK
安裝工具依賴包
1. 安裝xcode命令行工具
$ xcode-select --install
對於老版本的Mac OS系統(10.8或者10.8之前的),我們需要到蘋果開發者站點進行下載安裝.
如果你還沒有注冊成為蘋果開發者,你需要先注冊一個蘋果賬號來進行下載.
2. 到 macports.org 上下載對應Mac OS版本的macports(類似於Linux下的apt-get,用來幫助你安裝其他應用程序)
注意:確保
/opt/local/bin
在路徑/usr/bin
前,如果沒有,在~/.bash_profile
文件中進行添加
export PATH=/opt/local/bin:$PATH
注意:如果根目錄下沒有
.bash_profile
文件,那就手動創建一個
3. 通過macports安裝make, git以及GPG
$ POSIXLY_CORRECT=1 sudo port install gmake libsdl git gnupg
如果使用的是Mac OS X v10.4版本的系統,還需要安裝bison:
$ POSIXLY_CORRECT=1 sudo port install bison
注意:如果是編譯Android 4.0.x及以下版本的系統,gmake 3.8.2版本存在一個bug,需要還原到gmake 3.8.1
優化編譯環境(可選)
設置ccache
我們可以自由選擇是否開啟ccache編譯工具。
ccache是一個高速編譯緩存工具,它通過將頭文件高速緩存到源文件之中而改進了構建性能,因而通過減少每一步編譯時添加頭文件所需要的時間而提高了C\C++的構建速度。
從編譯的全過程來看,不使用ccache的情況下,編譯過程中會多次解析相同的頭文件,浪費了處理器周期,更重要的是浪費了開發者的時間,因為他們要等待這一過程的完成。在一個團隊中,這一影響可能會更為明顯,因為團隊成員可能會反復編譯解析相同的頭文件。
所以,一般對於專門用來編譯系統的服務器或是大容量的生產環境,這個功能比較有用,它可以加速重新編譯的速度。
注意:如果你只是個人開發者,不是專門的編譯服務器,不需要進行增量構建的話,那么使用ccache可能會因為高速緩存缺失而降低你的構建速度。
開啟ccache
要開啟ccache,在源碼樹的根路徑下執行下面的指令:
緩存的大小一般設置為50G-100G
接着在 .bashrc (或者etc/profile)中添加下面的指令
export USE_CCACHE=1
默認情況下,緩存會存在home根目錄的~/.ccache中,但是如果你使用的是NFS或者其他的非本地文件系統,那么你同樣需要在.bashrc指定緩存目錄地址
在Mac OS的系統中,你需要將linux-x86替換成darwin-x86:
prebuilts/misc/darwin-x86/ccache/ccache -M 50G
當編譯的Android系統是4.0.x或者更老的版本,ccache的緩存路徑會有所不同
prebuilt/linux-x86/ccache/ccache -M 50G
這個設置會一直存儲在CCACHE_DIR中。
在Linux上,你可以通過以下指令開啟對ccache的監聽:
$ watch -n1 -d prebuilts/misc/linux-x86/ccache/ccache -s
下載源碼
編譯環境配置好之后,我們就可以開始下載我們的源碼了
安裝Repo
Repo是google用Python寫的一個腳本工具,Android使用git作為代碼管理工具,一個Android系統由N多個git庫構成,如果手動進行一個個下載,那簡直是一件非常痛苦的事,而repo就是用來對這些git庫進行維護管理跟下載的。
通過Repo工具,我們可以輕松地完成Android系統源碼的下載。
1.在系統home根路徑下創建bin目錄並且添加到path路徑中:
2.下載repo工具並設置其可執行
初始化Repo客戶端
1.創建一個空目錄用來存放我們的Android系統源碼,名字自己隨便定
2.初始化repo倉庫
從主干master下載源碼,目前最新版本
如果需要下載某個特定版本系統的分支,可以在上述命令后加-b 版本分支號,這里我指定Android 7.0的版本分支
具體的版本分支號可以到這個地址查看(需要翻牆):
Android系統個版本分支號
3.同步源碼到本地
這時執行sync指令便可以自動下載源碼到本地了
使用國內鏡像下載源碼
由於國內網絡的問題,上述操作的源碼下載需要翻牆才能進行,速度會受到很大影響,幾十G的系統源碼可能需要花上上周的時間才能下完,
因此我們可以選擇國內的鏡像進行源碼下載:
清華大學的鏡像站
參照頁面上的描述對上面的指令稍作調整便可以了,站點上寫得比較詳細,這里我們就不作贅述了。
根據網速的不同,一般一天之內能夠下載完畢。
對於下載下來的源碼,我們並不能直接刷到我們的目標設備上或者是使用模擬器運行,我們必須對源碼進行編譯生成對應的image二進制鏡像文件,
當然你也可以直接從官網下載對應系統版本的鏡像文件:
里我們還是自己來編譯下源碼,熟悉下整個編譯過程。
源碼編譯
首先我們通過命令行進入到源碼目錄中,我這里目錄的名稱是aosp
cd aosp
清空輸出目錄
為了確保我們編譯生成的文件不受之前build構建的文件影響,我們在源碼目錄中執行下面的指令,該指令會清空out輸出目錄中的所有文件
$ make clobber
設置編譯環境
首先我們通過源碼build目錄中的 envsetup.sh
腳本文件初始化我們的編譯環境,執行
$ source build/envsetup.sh
或
$ . build/envsetup.sh
這兩個指令的效果是一樣的,會初始化一些有用的命令工具
我們后面執行的一些指令必須在初始化 envsetup
之后才能執行
選擇編譯目標
接着我們通過 lunch
指令來選擇我們需要編譯的目標
執行lunch指令
$ lunch
會彈出可選目標項:
所有的構建目標由BUILD-BUILDTYPE的形式組成:
BUILD對應codename
這是官方提供的一份對照表:
這是官方提供的一份對照表:
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 對照表:
構建類型 | 用途 |
---|---|
user | 有限的訪問權限,主要用於發布正式產品,沒有root跟調試權限 |
userdebug | 跟user類型差不多,但是多了root跟debug調試權限 |
eng | 擁有各種調試工具的開發版設置,擁有root跟debug權限 |
如果作為開發使用的話,那我們一般都是選 -eng,
這里我自己是准備在模擬器上運行編譯的image鏡像,並且我電腦的cpu是intel x86的,所以我選擇了 6. aosp_x86-eng
我們可以根據自己的需要選擇對應的cpu類型。
注意:我們知道,Android官方的模擬器速度很慢,
Intel特意提供了一個叫HAXM的虛擬硬件加速技術,全稱為:Intel Hardware Accelerated Execution Manager.只要你的CPU是intel的產品並且支持VT(virtualization Technology)就可以使用HAXM技術將你的模擬器的速度提升至真機的水平。
目前Intel只提供了windows版和MAC版,Linux系統只有通過安裝KVM來達到這個效果。
安裝KVM
首先我們檢測下自己的cpu是否支持 hardware virtualization(硬件虛擬化)
egrep -c '(vmx|svm)' /proc/cpuinfo
輸出的值如果是大於0的,則表明你的cpu支持
如果你使用的是vmware虛擬機安裝的linux,注意要設置下虛擬機的cpu來支持硬件虛擬化,先關閉虛擬機,然后右鍵虛擬機=》設置,選中cpu,勾選虛擬化Intel VT項,這樣就能支持KVM了。
對於Ubuntu 10.0.4以上的版本,我們通過下面的指令安裝KVM即可
sudo apt-get install qemu-kvm libvirt-bin ubuntu-vm-builder bridge-utils
如果在安裝KVM的過程中有什么疑問的話,可以訪問下面這個網址查找方法:https://help.ubuntu.com/community/KVM/Installation
這樣,在編譯完目標intel cpu的鏡像文件后,我們運行模擬器就會自動進行加速了。
編譯源碼
好了,一切就緒,我們可以開始編譯我們的源碼了,
我們在源碼路徑下通過 make -jN
指令來進行源碼編譯,這里的N一般建議設置為cpu核心線程數的1-2倍。
$ make -j4
一般情況下,我們等待源碼編譯完成就可以了,不過從Android 7.0 N開始,make指令默認會開啟Jack編譯工具鏈來進行Java代碼的編譯,這個過程中可能會出現一些問題。
什么是Jack編譯工具鏈(The Jack toolchain)?
我們知道,我們平時編譯Android代碼的時候會先將Java代碼編譯成.class文件,最終再轉換成.dex文件,如圖:
而Jack編譯工具鏈則跳過了編譯成.class文件這一過程,直接將Java代碼編譯成.dex文件
它的優勢:
-
完全開放源碼
源碼均在AOSP中,合作伙伴可貢獻源碼 -
加快編譯源碼
Jack 提供特殊的配置,減少編譯時間:pre-dexing, 增量編譯和Jack編譯服務器. -
支持代碼壓縮,混淆,重打包和multidex
-
不在使用額外單獨的包,例如ProGuard。
如果想進一步了解Jack,可以訪問Compiling with Jack(需翻牆),這里就不作太多解釋了。
按照官方的說法Jack可以加快編譯速度
但實際編譯過程中,在我的設備上Jack會占用大量內存,並且拖慢編譯速度,還會報錯,而且官方文檔上寫的配置方式對Jack並不起作用。
Jack編譯過程中遇到的問題
編譯過程中報Out of memory error並中斷編譯
在執行make指令后,當第一次編譯Java代碼的時候,Jack會被啟用,這個時候經常會卡住,並且一段時間后報錯Out of memory error。
按照官方的說法,Jack並行編譯的時候占用的資源太大導致內存溢出了
可以通過在 $HOME/.jack
文件中減小 SERVER_NB_COMPILE
的值來減小並行編譯數量, SERVER_NB_COMPILE
的值默認為4
但實際情況是Jack沒有在根路徑下生成 .jack
文件,並且手動創建設置 SERVER_NB_COMPILE
后重啟Jack服務也沒有效果。
經測試發現make編譯過程中當Jack第一次被啟用時會在home根路徑下生成.jack-server目錄
可以通過修改該目錄中config.properties文件里的
值來設置並發線程數。
.jack.server.max-service
同時,你也可以設置增加Jack的內存容量來解決這個問題,指令如下
export JACK_SERVER_VM_ARGUMENTS="-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx4096m"
然后進入到輸出路徑的bin目錄下:
cd /home/cjpx00008/aosp/out/host/linux-x86/bin
執行下面的指令重啟Jack服務
./jack-admin stop-server./jack-admin start-server
我改了service大小,同時增加了內存,后來編譯的過程中沒有發生其他問題。
有辦法關閉Jack編譯嗎?
既然Jack有問題,那我們可以關閉Jack編譯嗎?
目前來說我還沒有找到如何在Android 7.0編譯的時候關閉Jack,如果有知道的小伙伴歡迎留言告訴我哈,感激不盡!!
運行編譯出的image鏡像
經過漫長的等待,我們的源碼終於編譯結束了,是時候來運行編譯出的image鏡像了。
這時我們只要在源碼目錄下執行 emulator
指令即可運行模擬器
$ emulator
第一次啟動時間可能會有點長,耐心等待即可
運行成功了,是不是有點小激動呢!
注意:如果你的命令行窗口關閉重開了,那emulator指令可能會提示找不到命令,我們可以在源碼根目錄環境下,通過envsetup.sh重新初始化命令,運行lunch指令選擇編譯目標,這個時候你再運行emulator就不會提示找不到指令了(每次關閉命令行窗口都需要重新運行如下指令才能執行emulator)
也可以通過配置環境變量來設置emulator指令,不過我沒有成功,哈哈
$ source build/envsetup.sh$ lunch$ emulator
好啦,到此,我們的源碼就編譯完畢啦,下一篇我們來聊聊如何使用Android Studio導入Android系統源碼,並通過AS進行Java源碼調試,以及使用GDB來調試系統Native C\C++源碼。
到了這里,就是一長篇文章告一段落了,之后對Java代碼調試,通過命令行實現。 (*打個星號)
開始...
我們知道,Android Framework 的代碼主要由Java、C\C++等代碼組成,因此,對於系統源碼的調試,我們這里將其分為了兩部分
1. Java 相關代碼的調試
2. C\C++ Native 相關代碼的調試
一、Java 相關代碼的調試
對於 Java 相關代碼的調試,這里我們主要使用 Android Studio 開發工具來進行。
導入源碼到 Android Studio
要在 Android Studio 中調試源碼,那第一步自然是導入系統源碼到 Android Studio 中了。
1. 編譯 idegen
對於 Android 源碼的導入, Google 官方給我們提供了一個很方便的工具idegen
它位於我們所下載的系統源碼路徑中:
developement/tools/idegen
(這個位置我找了很久,沒找到)
引用 README 的一句話
IDEGen automatically generates Android IDE configurations for IntelliJ IDEA and Eclipse.
idegen 工具會自動生成針對 Android 開發工具(Android Studio和Eclipse)的配置文件。 既然如此,那我們就來使用 idegen 工具生成導入源碼所需的配置文件。
首先打開命令行工具,cd 進入到源碼路徑下,
執行如下指令:
#初始化命令工具 soruce build/envsetup.sh #編譯 idegen 模塊,生成idegen.jar mmm development/tools/idegen/ #生成針對 Android 開發工具的配置文件 sudo ./development/tools/idegen/idegen.sh
在執行完上述指令后,會在源碼路徑下生成下面三個文件
android.ipr:工程相關的設置,比如編譯器配置、入口,相關的libraries等。 android.iml:描述了modules,比如modules的路徑,依賴關系等。 android.iws:包含了一些個人工作區的設置。
2. 導入源碼
接下來我們可以開始導入源碼了.
如果你是第一次導入源碼, Android Studio 可能需要占用大量的內存,我們需要設置下我們的 VM 選項。
Linux 設備的話在 Android Studio 的 bin/studio64.vmoptions 文件中添加-Xms748m -Xmx748m,
如果你使用的是 Mac ,那么在 AS 目錄的 Contents/Info.plist 目錄中進行添加。
由於 Android 的系統源碼非常龐大,一次性導入 Android Studio 的話需要加載非常長的時間
因此,在正式開始導入前,我們可以打開 android.iml 文件根據自己需要調整要加載的源碼。
這里 表示不需要加載的目錄,我們根據自己的需要使用 標簽添加對應的目錄地址即可。
接着,選擇 File -> open 選中 android.ipr 文件,打開
這時 Android Studio 就會開始加載源碼了
在沒有添加修改 的情況下,這個加載的時間會比較長,經過一段時間的等待后,代碼就加載完畢了,如圖:
這里紅色的目錄代表被 exclude 排除了,代碼加載 scan index 的時候會過濾掉該目錄。
在加載完源碼后,我們也可以在 Project Structure 中的 Module 選項中右鍵 exclude 來排除不需要加載的源碼目錄,如圖:
3. 配置代碼依賴,確保代碼跳轉正確
為了閱讀和調試代碼的時候能夠保證代碼跳轉正確,我們需要配置下相關依賴。
首先是 AOSP 源碼的跳轉,我們通過 File -> Project Structure 打開 Module,然后選中 Dependencies, 保留 JDK 跟 Module Source 項,並添加源碼的 external 和 frameworks 依賴,如圖:
然后是 SDK 的設置,確保關聯對應版本的 SDK 於系統版本一直
開始調試源碼
調試前要設置 Project 的 SDK ,File -> Project
下打開 Project Structure,選中 Project 設置對應版本的 SDK,於系統版本一致:
確保 Android Studio 允許 ADB 調試
接着我們參照上一篇文章中講的方法打開 Android 模擬器
此時點擊 Android Studio 工具欄的 attach debugger to Android process 按鈕,會打開 Choose Process 窗口,我們根據自己需要調試的代碼選擇對應的進程:
這里假設我們要調試 Android 自帶瀏覽器的源碼,如圖,我們在它的入口文件 WebViewBrowserActivity 中的 loadUrlFromUrlBar 方法中打上斷點。
點擊 WebViewBrowser 打開 app
打開之后,點擊 attach to Android process 按鈕打開 choose Process,可以看到 webViewBrowser 運行的進程,選中,ok
然后我們在 app 的 url 輸入欄輸入 網址進行跳轉
如圖所示我們可以看到,代碼成功進入了斷點,然后我們就可以隨心所欲地調試我們想要的調試的 Java 代碼了。
二、Native C\C++ 相關代碼調試
對於 Framework Native 代碼,我們這里使用 GDB 工具來進行調試。
什么是 GDB 呢?
它是一款 GNU 項目調試工具,它的功能非常強大,可以用來調試 C 、C++、Object-C、Pascal 等語言編寫的項目。
對於使用習慣了可視化 IDE 的同學們來說,它最大的缺點可能就是它不支持圖形化了
但是 GDB 提供的指令非常靈活,通過指令我們
-
可以隨心所欲地啟動程序,
-
可以根據自己的需要設置斷點,
-
可以查看斷點處的變量,代碼信息
-
可以查看程序運行的調用棧
一旦你熟悉了它,你便可以玩得飛起!
一般情況下,使用 gdb 來調試 Android 源碼需要在 Android 設備上安裝 gbdserver attach 關聯我們需要調試的進程,再使用 gdb 指令去連接 gdbserver 進行調試
不過官方給我們提供了 gdbclient 工具,可以讓我們方便地進行 gdb 調試。
開始 GDB 調試
這里我們就基於 gdbclient 來進行實際的 gdb 調試演示:
跟上面 Java 調試一樣,我們這里還是以系統自帶的瀏覽器為例。
-
點擊啟動圖標打開瀏覽器 app:
-
打開一個命令行終端,cd 進入到系統源碼目錄(我的源碼路徑為 aosp),初始化命令工具:
#進入源碼路徑
cd aosp #初始化命令工具 source build/envsetup.sh #選擇編譯的源碼的版本,參考上一篇文章 lunch -
通過 adb 指令來查找要調試進程的 PID
#通過 shell ps 指令查找相關進程,grep 搜索過濾 webview 進程 adb shell ps -A | grep webview
如圖,2157 為系統自帶瀏覽器 app 所在進程的 PID
-
使用 gdbclient 命令工具啟用 gdb 調試 PID 對應進程
# gdbclient <app pid> 可以啟用 gdb 調試對應 PID 進程 gdbclient 2157
等待進入 gdb 調試命令界面
-
使用 GDB b 命令打斷點
在 gdb 指令中,我們使用b <代碼文件>:行號 來設置斷點.
這里我們選擇 frameworks/base/libs/hwui/renderthread/DrawFrameTask.cpp 代碼文件的 drawFrame 方法打上斷點,位於文件 71 行:
該方法主要用於繪制幀,當瀏覽器 app 的界面發生變化時會觸發該方法。
我們輸入設置斷點命令:
b frameworks/base/libs/hwui/renderthread/DrawFrameTask.cpp:71
輸入指令后顯示 Breakpoint 2 at 0x7f69e9892c11: file frameworks/base/libs/hwui/renderthread/DrawFrameTask.cpp, line 71. 說明我們的斷點設置成功了。
-
在命令行輸入c 開始監聽
c 即 continue,此時界面上出現 Continuing 說明開始監聽進程了
我們點開模擬器,隨意操作,觸發界面變化時,便會進入繪制幀的代碼斷點了:
如圖,顯示進入斷點,這樣代表我們的代碼調試成功了。
這里我們只是演示了一個大概流程
gdb 代碼的調試需要你對源碼有一定的熟悉,知道哪個進程會調用哪個文件方法。
同時,我們還需要熟悉 gdb 的各種命令,這里給大家推薦一篇不錯的入門文章,可以快速入門:
這里補充一點,如果你希望在某個進程啟動時就監聽,可以使用下面的指令關聯目錄,得到 pid,再通過 gdbclient 來進行調試
adb shell gdbserver :5039 /system/bin/my_test_app Process my_test_app created; pid = 3460 Listening on port 5039 gdbclient <app pid>
如果你希望通過 Android Studio 來調試 Framework 的 C\C++ 代碼的話,也可以參考下面的兩篇文章,不過個人覺得這種方法有一定的局限性。
兩篇文章先到這里結束,技術文章很多,但是真正使用起來又可以總結出新的結論和技術操作上的更新。
轉載出自:https://juejin.im/entry/5934cfd8fe88c20061ccc63e 謝謝提供!