** 這是一個連載的博文系列,我將持續為大家提供儘可能透徹的Android原始碼分析 github連載地址**
前言
閱讀Android原始碼的好處有很多,可以加深我們對系統的瞭解,可以參考牛人優雅的程式碼實現,可以從根本上找出一些bug的原因...我們應該慶幸Android是開源的,所有的功能都可以看到實現,所有的bug都能追蹤溯源。
我想大家或多或少聽說過Android原始碼開源專案,即AOSP(Android Open Source Project) ,有些人可能還不知道如何下載AOSP,有些人雖然下載下來了,但是面對龐大的Android原始碼專案又望而卻步,不知道從哪兒下手。
所以本文將從以上兩個問題出發,具體講解如何下載和閱讀Android系統原始碼。
一、如何下載AOSP
原始碼下載是我們分析原始碼的開始,Android原始碼可以全量下載,也可以單個下載,我們先介紹全量下載
1.1 全量下載
官方文件 ,只要按照上面一步步做就可以了,但是由於需要翻牆,國內無法直接訪問,而整個Android專案原始碼巨大,即便是翻牆後下載也很慢,所以還是使用國內映象比較好。
我推薦清華大學開源映象,地址 ,這上面也是有完整的教程,我就不復制貼上了,但是有一點要注意,你一定要備一個比較大的磁碟,至少60個G吧,還不算後期編譯的。
我們分析原始碼其實是不需要全部程式碼的,因為AOSP不僅包括系統原始碼,還有些工具程式碼,如aapt,adb等,這些我們根本不需要,而且即便是系統原始碼,也不是所有我們都需要看,如果真的全部看,你這輩子都看不完,所以我還是推薦大家單個下載。
1.2 單個下載
官方地址 ,比如我們要下載platform/frameworks/base/目錄下的程式碼,我們可以git clone https://android.googlesource.com/platform/frameworks/base ,不過這個還是會遇到翻牆的問題,當然我們也可以用映象。
映象地址 ,比如我們要下載platform/frameworks/base/目錄,就用git clone https://aosp.tuna.tsinghua.edu.cn/platform/frameworks/base ,如果你頻寬夠的話,一般幾分鐘就可以下載好你想要的單個原始碼了。
如果你想下載單個檔案,或者搜尋檔名及程式碼,可以訪問 http://androidxref.com/ ,這裡有部分Android的原始碼
1.3 AOSP目錄結構
先上一張圖,整個Android專案的架構圖
我們都知道Android系統從上到下大致分為這四層,所以我們以這四層為基礎,講解下AOSP的目錄結構:
- 第一層:應用程式層(applications)對應根目錄下 platform/packages/apps
- 第二層:應用程式框架層(application framework)對應根目錄下的 platform/frameworks
- 第三層:執行庫層包括執行庫(libraries)和android執行時環境(android runtime)
- libraries對應目錄很多,其中libc庫對應的是 platform/bionic
- android執行時環境,Core Libraries 對應根目錄下的 platform/libcore,Dalvik Virtual Machine 對應根目錄下的 platform/dalvik ,不過現在已經是ART了,所以目錄是 platform/art
- 第四層:Linux核心層對應根目錄下的 kernel,每一個目錄對應了一個kernel的版本,因為Android要相容各種晶片,下面羅列一下:
- goldfish 專案包含適用於所模擬的平臺的核心原始碼。
- msm 專案包含適用於 ADP1、ADP2、Nexus One、Nexus 4、Nexus 5、Nexus 6、Nexus 5X、Nexus 6P、Nexus 7 (2013)、Pixel 和 Pixel XL 的原始碼,可用作使用 Qualcomm MSM 晶片組的起點。
- omap 專案用於 PandaBoard 和 Galaxy Nexus,可用作使用 TI OMAP 晶片組的起點。
- samsung 專案用於 Nexus S,可用作使用 Samsung Hummingbird 晶片組的起點。
- tegra 專案用於 Xoom、Nexus 7 (2012)、Nexus 9,可用作使用 NVIDIA Tegra 晶片組的起點。
- exynos 專案包含適用於 Nexus 10 的核心原始碼,可用作使用 Samsung Exynos 晶片組的起點。
- x86_64 專案包含適用於 Nexus Player 的核心原始碼,可用作使用 Intel x86_64 晶片組的起點。
- hikey-linaro 專案用於 HiKey 參考板,可用作使用 HiSilicon 620 晶片組的起點。
- 第三層和第四層中間還有個硬體抽象層(HAL)對應根目錄下的 platform/hardware
目前我下載的目錄如下:
git clone https://aosp.tuna.tsinghua.edu.cn/platform/packages/apps/Launcher2
git clone https://aosp.tuna.tsinghua.edu.cn/platform/frameworks/base
git clone https://aosp.tuna.tsinghua.edu.cn/platform/frameworks/native
git clone https://aosp.tuna.tsinghua.edu.cn/platform/system/core
git clone https://aosp.tuna.tsinghua.edu.cn/platform/bionic
git clone https://aosp.tuna.tsinghua.edu.cn/platform/libcore
git clone https://aosp.tuna.tsinghua.edu.cn/platform/art
git clone https://aosp.tuna.tsinghua.edu.cn/kernel/msm
二、如何閱讀AOSP
當我們把原始碼下載下來之後,會感到茫然無措,因為AOSP的原始碼實在是太多了,這裡我們需要明確一些問題:
- 要閱讀哪些原始碼
- 閱讀原始碼的順序和方式
- 用什麼工具來閱讀
下面我將從這三個問題一一展開
2.1 要閱讀哪些原始碼
這個問題是比較個性化的,因為不同的人從事著不同的工作,有的人從事應用開發,可能對Java層東西感興趣;有的人從事Framework開發,可能對Framework層感興趣;有的從事硬體開發,可能對底層實現感興趣。
這個都因人而異,但是有一點,不能盲目地毫無目的地看原始碼,因為這樣的話最終你會淹沒在AOSP的大海里,看了一年半截啥都看了,卻又感覺都沒看透,別人問你原始碼的東西,都能說個一二,但是一往深了說,就不知所以了。
所以對於AOSP原始碼,不在於多,而在於精,你不要試圖把所有的原始碼都看懂,你只要對自己感興趣的那部分深入研究就可以,因為即便是Google工程師也不可能把AOSP全部讀完。
對於我而言,我是從事應用層開發的,我主要會了解以下幾個方面的原始碼:
- Android系統啟動流程,應用啟動流程,四大元件啟動流程,這將列入系統啟動篇
- 系統常用服務ActivityManagerService,WindowManagerService等,這將列入系統服務篇
- 通訊機制,主要是Binder和Handler,這將列入通訊篇
- 程式和執行緒的建立,執行,銷燬,這將列入程式篇
- View的繪製和顯示流程,事件分發機制,這將列入圖形繪製篇
- Android虛擬機器ART執行機制,類載入機制,Java註解,Java反射,這將列入虛擬機器篇
- Android對於Java集合的優化演算法,這將列入Java基礎篇
2.2 閱讀原始碼的順序和方式
2.2.1 閱讀順序
讀原始碼是一個日積月累的過程,不可能一蹴而就,當我們列出自己感興趣的原始碼後,我們需要制定一個閱讀計劃,先讀什麼再讀什麼。這個也是因人而異,根據自己的興趣來就是,你最想讀什麼,那就排前面。
我一直在說興趣,因為興趣是最好的老師,只有你對一樣東西感興趣了,才會有動力去學,去研究,才會不覺得累,如果一開始就去啃一些你不感興趣的東西,到頭來也是乏味不專注的,理解的程度也是不深,而且很有可能失去信心,最後放棄閱讀。
當然,如果你對好幾樣東西都感興趣,那就有一些原則了:
- 事物都講究先後,就像樹木紮根大地一樣,先有大地,才有樹木,基礎的東西先看
- 相互有關聯的東西一起看,不要一會兒看系統啟動,突然又去看事件分發什麼的
2.2.2 閱讀方式
Android系統涵蓋的範圍很廣,從上層的應用程式,到Framework,再到Libraries以至硬體,從Java層到C++,就像一座幾十層的大廈一樣,每層都有樓梯,也有電梯,我們需要做的就是在大廈裡上下穿梭。
當我們閱讀某一個知識點原始碼的時候,不同的知識點有不同的閱讀方式,有些適合從下往上讀,比如系統啟動流程,我是從事件開始的地方開始讀,從init.cpp開始,然後到zygote程式,到Java虛擬機器,最後到Luncher;
有些適合從上往下讀,比如Activity的啟動,我是從startActivity方法開始讀,然後到ActivityThread,然後到ActivityManagerService;
有些適合兩頭從中間讀,比如Binder,我是從Java層看到C++層,但是看到驅動那兒看不動了,然後就從接收Binder的地方往回看,最後在兩端集中在驅動的地方前後對比,才將Binder看通。
這裡還是有個好的方式,就是從事件觸發的地方開始看是比較合適的。
2.3 用什麼工具來閱讀
Android 原始碼閱讀神器當然是Source Insight
Source Insight的好處:
- 支援方法跳轉,類跳轉,並且對C++支援很好
- 支援檔案搜尋,java,c++,xml都支援,並且支援內容搜尋
- 支援一鍵匯入,隨時配置路徑
- 而且最重要的,匯入檔案數多的時候不卡
下面我講講如何使用Source Insight
2.3.1 下載安裝Source Insight
下載地址 http://download.csdn.net/download/foxlee1991/9882553 ,我還專門配置了一個跟Android Studio一樣的Darcula主題,下載地址 http://download.csdn.net/download/foxlee1991/9882535
2.3.2 匯入AOSP原始碼
我目前還沒有下載完整的AOSP原始碼,只是先下載了幾個重要的原始碼。開啟Source Insight,選擇Project -> New Project,取個名字比如叫AOSP,點選OK
選擇你要檢視的原始碼目錄,點選OK
選擇需要將哪些目錄下的原始碼匯入,點選Add Tree
匯入成功後會有很多檔案列在下方,點選Close
2.3.3檢視原始碼
現在進入專案還是一片空白,需要把工具欄開啟,然後就可以看原始碼了
左邊是方法和成員變數搜尋,右邊Project File是搜尋類名,Project Symbol是內容搜尋
還有一些快捷鍵,比如Ctrl+左鍵可以方法跳轉,左上角有前進和後退,Ctrl+G 是跳轉到指定行,Ctrl+F 搜尋內容,有時我們會遇到方法無法跳轉,這時我們需要點選Project,選擇Synchronize Files,全域性關聯一下,如圖
這裡要注意匯入的檔案不要太多,太多會導致Synchronize失敗,我們可以選擇性地匯入一些目錄
我們在匯入原始碼的時候,有時一些彙編的原始碼(以.s或.S結尾)無法匯入,這時我們需要點選Options,選擇File Type Options,在C/C++裡新增.s和.S的支援,然後Close,如圖
然後我們重新追加一些目錄,點選Project,選擇Add and Remove Projec Files,選擇對應目錄Add Tree即可,同時我們也可以選擇Remove Tree刪除對應目錄原始碼,操作如下
三、 其他
在真正開始閱讀Android原始碼之前,最好是去了解一些C/C++的語法知識,因為原始碼核心的部分都是用C/C++寫的,如果你對一些基礎語法不太瞭解,會看得雲裡霧裡的,這裡我給大家推薦兩本書《C標準庫 中文版》和《C++標準庫 中文第2版》,另外一些學習網站也不錯:
我自己本身也剛開始閱讀Android原始碼,準備整理一些閱讀筆記,我在github上建了專案,會把筆記以issue的方式展示,方便大家交流,另外我會把閱讀的一些原始碼拷貝到Android Studio專案中,保持原有目錄結構,方便大家看筆記時找到對應的原始碼,專案地址
關於我
- foxleezh
- 我的部落格
- github
- 郵箱-foxleezh@gmail.com