Android FrameWork学习(二)Android系统源码调试
通過上一篇 Android FrameWork學習(一)Android 7.0系統(tǒng)源碼下載\編譯 我們了解了如何進行系統(tǒng)源碼的下載和編譯工作。
為了更進一步地學習跟研究 Android 系統(tǒng)源碼,今天我們來講講如何進行 Android 系統(tǒng)源碼的調(diào)試,只有學會了如何進行系統(tǒng)源碼的調(diào)試,才能幫助我們更高效地閱讀跟理解源碼。
我們知道,Android Framework 的代碼主要由Java、C\C++等代碼組成,因此,對于系統(tǒng)源碼的調(diào)試,我們這里將其分為了兩部分
1. Java 相關(guān)代碼的調(diào)試
2. C\C++ Native 相關(guān)代碼的調(diào)試
一、Java 相關(guān)代碼的調(diào)試
對于 Java 相關(guān)代碼的調(diào)試,這里我們主要使用 Android Studio 開發(fā)工具來進行。
導入源碼到 Android Studio
要在 Android Studio 中調(diào)試源碼,那第一步自然是導入系統(tǒng)源碼到 Android Studio 中了。
1. 編譯 idegen
對于 Android 源碼的導入, Google 官方給我們提供了一個很方便的工具 idegen
它位于我們所下載的系統(tǒng)源碼路徑中:
developement/tools/idegen- 1
引用 README 的一句話
IDEGen automatically generates Android IDE configurations for IntelliJ IDEA
and Eclipse.
idegen 工具會自動生成針對 Android 開發(fā)工具(Android Studio和Eclipse)的配置文件。
既然如此,那我們就來使用 idegen 工具生成導入源碼所需的配置文件。
首先打開命令行工具,cd 進入到源碼路徑下,
執(zhí)行如下指令:
#初始化命令工具 soruce build/envsetup.sh #編譯 idegen 模塊,生成idegen.jar mmm development/tools/idegen/ #生成針對 Android 開發(fā)工具的配置文件 sudo ./development/tools/idegen/idegen.sh- 1
- 2
- 3
- 4
- 5
- 6
在執(zhí)行完上述指令后,會在源碼路徑下生成下面三個文件
android.ipr:工程相關(guān)的設(shè)置,比如編譯器配置、入口,相關(guān)的libraries等。
android.iml:描述了modules,比如modules的路徑,依賴關(guān)系等。
android.iws:包含了一些個人工作區(qū)的設(shè)置。
2. 導入源碼
接下來我們可以開始導入源碼了.
如果你是第一次導入源碼, Android Studio 可能需要占用大量的內(nèi)存,我們需要設(shè)置下我們的 VM 選項。
Linux 設(shè)備的話在 Android Studio 的 bin/studio64.vmoptions 文件中添加-Xms748m -Xmx748m,
如果你使用的是 Mac ,那么在 AS 目錄的 Contents/Info.plist 目錄中進行添加。
由于 Android 的系統(tǒng)源碼非常龐大,一次性導入 Android Studio 的話需要加載非常長的時間
因此,在正式開始導入前,我們可以打開 android.iml 文件根據(jù)自己需要調(diào)整要加載的源碼。
這里 <excludeFolder> 表示不需要加載的目錄,我們根據(jù)自己的需要使用 <excludeFolder> 標簽添加對應(yīng)的目錄地址即可。
接著,選擇 File -> open 選中 android.ipr 文件,打開
這時 Android Studio 就會開始加載源碼了
在沒有添加修改 <excludeFolder> 的情況下,這個加載的時間會比較長,經(jīng)過一段時間的等待后,代碼就加載完畢了,如圖:
這里紅色的目錄代表被 exclude 排除了,代碼加載 scan index 的時候會過濾掉該目錄。
在加載完源碼后,我們也可以在 Project Structure 中的 Module 選項中右鍵 exclude 來排除不需要加載的源碼目錄,如圖:
3. 配置代碼依賴,確保代碼跳轉(zhuǎn)正確
為了閱讀和調(diào)試代碼的時候能夠保證代碼跳轉(zhuǎn)正確,我們需要配置下相關(guān)依賴。
首先是 AOSP 源碼的跳轉(zhuǎn),我們通過 File -> Project Structure 打開 Module,然后選中 Dependencies, 保留 JDK 跟 Module Source 項,并添加源碼的 external 和 frameworks 依賴,如圖:
然后是 SDK 的設(shè)置,確保關(guān)聯(lián)對應(yīng)版本的 SDK 于系統(tǒng)版本一直
開始調(diào)試源碼
調(diào)試前要設(shè)置 Project 的 SDK , File -> Project 下打開 Project Structure,選中 Project 設(shè)置對應(yīng)版本的 SDK,于系統(tǒng)版本一致:
確保 Android Studio 允許 ADB 調(diào)試
接著我們參照上一篇文章中講的方法打開 Android 模擬器
此時點擊 Android Studio 工具欄的 attach debugger to Android process 按鈕,會打開 Choose Process 窗口,我們根據(jù)自己需要調(diào)試的代碼選擇對應(yīng)的進程:
這里假設(shè)我們要調(diào)試 Android 自帶瀏覽器的源碼,如圖,我們在它的入口文件 WebViewBrowserActivity 中的 loadUrlFromUrlBar 方法中打上斷點。
點擊 WebViewBrowser 打開 app
打開之后,點擊 attach to Android process 按鈕打開 choose Process,可以看到 webViewBrowser 運行的進程,選中,ok
然后我們在 app 的 url 輸入欄輸入 網(wǎng)址進行跳轉(zhuǎn)
如圖所示我們可以看到,代碼成功進入了斷點,然后我們就可以隨心所欲地調(diào)試我們想要的調(diào)試的 Java 代碼了。
二、Native C\C++ 相關(guān)代碼調(diào)試
對于 Framework Native 代碼,我們這里使用 GDB 工具來進行調(diào)試。
什么是 GDB 呢?
它是一款 GNU 項目調(diào)試工具,它的功能非常強大,可以用來調(diào)試 C 、C++、Object-C、Pascal 等語言編寫的項目。
對于使用習慣了可視化 IDE 的同學們來說,它最大的缺點可能就是它不支持圖形化了
但是 GDB 提供的指令非常靈活,通過指令我們
* 可以隨心所欲地啟動程序,
* 可以根據(jù)自己的需要設(shè)置斷點,
* 可以查看斷點處的變量,代碼信息
* 可以查看程序運行的調(diào)用棧
一旦你熟悉了它,你便可以玩得飛起!
一般情況下,使用 gdb 來調(diào)試 Android 源碼需要在 Android 設(shè)備上安裝 gbdserver attach 關(guān)聯(lián)我們需要調(diào)試的進程,再使用 gdb 指令去連接 gdbserver 進行調(diào)試
不過官方給我們提供了 gdbclient 工具,可以讓我們方便地進行 gdb 調(diào)試。
開始 GDB 調(diào)試
這里我們就基于 gdbclient 來進行實際的 gdb 調(diào)試演示:
跟上面 Java 調(diào)試一樣,我們這里還是以系統(tǒng)自帶的瀏覽器為例。
1. 點擊啟動圖標打開瀏覽器 app:
2. 打開一個命令行終端,cd 進入到系統(tǒng)源碼目錄(我的源碼路徑為 aosp),初始化命令工具:
#進入源碼路徑 cd aosp #初始化命令工具 source build/envsetup.sh #選擇編譯的源碼的版本,參考上一篇文章 lunch- 1
- 2
- 3
- 4
- 5
- 6
3. 通過 adb 指令來查找要調(diào)試進程的 PID
#通過 shell ps 指令查找相關(guān)進程,grep 搜索過濾 webview 進程 adb shell ps -A | grep webview- 1
- 2
如圖,2157 為系統(tǒng)自帶瀏覽器 app 所在進程的 PID
4. 使用 gdbclient 命令工具啟用 gdb 調(diào)試 PID 對應(yīng)進程
# gdbclient <app pid> 可以啟用 gdb 調(diào)試對應(yīng) PID 進程 gdbclient 2157- 1
- 2
等待進入 gdb 調(diào)試命令界面
5. 使用 GDB b 命令打斷點
在 gdb 指令中,我們使用b <代碼文件>:行號 來設(shè)置斷點.
這里我們選擇 frameworks/base/libs/hwui/renderthread/DrawFrameTask.cpp 代碼文件的 drawFrame 方法打上斷點,位于文件 71 行:
該方法主要用于繪制幀,當瀏覽器 app 的界面發(fā)生變化時會觸發(fā)該方法。
我們輸入設(shè)置斷點命令:
b frameworks/base/libs/hwui/renderthread/DrawFrameTask.cpp:71- 1
輸入指令后顯示
Breakpoint 2 at 0x7f69e9892c11: file frameworks/base/libs/hwui/renderthread/DrawFrameTask.cpp, line 71.
說明我們的斷點設(shè)置成功了。
6. 在命令行輸入c 開始監(jiān)聽
c 即 continue,此時界面上出現(xiàn) Continuing 說明開始監(jiān)聽進程了
我們點開模擬器,隨意操作,觸發(fā)界面變化時,便會進入繪制幀的代碼斷點了:
如圖,顯示進入斷點,這樣代表我們的代碼調(diào)試成功了。
這里我們只是演示了一個大概流程,
gdb 代碼的調(diào)試需要你對源碼有一定的熟悉,知道哪個進程會調(diào)用哪個文件方法。
同時,我們還需要熟悉 gdb 的各種命令,這里給大家推薦一篇不錯的入門文章,可以快速入門:
GDB十分鐘教程
這里補充一點,如果你希望在某個進程啟動時就監(jiān)聽,可以使用下面的指令關(guān)聯(lián)目錄,得到 pid,再通過 gdbclient 來進行調(diào)試
adb shell gdbserver :5039 /system/bin/my_test_app Process my_test_app created; pid = 3460 Listening on port 5039- 1
- 2
- 3
- 1
如果你希望通過 Android Studio 來調(diào)試 Framework 的 C\C++ 代碼的話,也可以參考下面的兩篇文章,不過個人覺得這種方法有一定的局限性。
如何調(diào)試Android Native Framework
用Android Studio調(diào)試Framework層代碼
總結(jié)
以上是生活随笔為你收集整理的Android FrameWork学习(二)Android系统源码调试的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安卓升级固件update.zip解析
- 下一篇: android ART编译预优化