原始碼閱讀的經驗總結
Android進階之旅 - 原始碼閱讀的經驗總結
在長沙待的那些年,身邊所看到的大概可分為兩類人,一類是不斷反覆的做業務邏輯,只求功能能夠寫出來,每天重複上下班,不想過多的去折騰;還有一類是不斷的反思總結和學習,不只停留在做的層次上,是真正的喜歡做這行,且覺得非常有意思。沒有什麼好與壞,只是大家的追求不同而已。但如果我們想要去大一點的公司,或者找一份工資稍微高些的工作,後面我們就會有很多坎要去邁,其中一個就是閱讀原始碼,所以這期我們主要來探討一下閱讀原始碼的 一些姿勢。在真正踏上這條路之前,希望我們能明確以下幾點:
沒有人一上來就可以看得懂原始碼,我們都是從 Hello World 開始的,所以沒有什麼捷徑可以走,無非就是看我們誰花的時間多,誰更願意折騰。
大家都是上下班,為啥別人工資拿得高福利又好,而自己大小周,偶爾還需要加班通宵。同樣三四年別人拿 20k,我自己卻只拿了 10k。注意我說的是 20k ,之前寫過一篇文章 《從3K到30K,23歲的年紀我到底經歷了什麼》 這次同樣怕某些哥們會噴,哪有那麼高?我們心中要有美好的信念,要有不斷向上的激情。
能力提升過程中我們能從中獲得很多東西,內心也會變強大,關鍵是我們在做專案的時候,的確會要順手很多,這就可以拿來換錢和時間,前提是我們願意拿時間去換。
一.常用工具
首先來介紹一些看原始碼的工具,第一個就是我們的開發工具 Android Studio ,這裡我們以具體的示例來說,假設現在我想看 setContentView 的原始碼,那麼我們可以直接跟進到原始碼的方法裡面去:
這時如果再往裡面跟發現是一個抽象類,我們必須要找到實現類,一般來講我們可以搜尋(ctrl + F)找到其建立例項的地方:
是紅色的,這個時候我們再也沒法往裡面跟了(一碰到紅尷尬症就犯了,腎得慌),碰到這種情況我們可以試試全域性的搜尋(雙擊 shift)
但很多情況下我們全域性搜尋也搜尋不到,接下來給大家介紹第二個工具,我們可以線上瀏覽原始碼閱讀:
線上檢視一般都是比較精確要看哪個類的時候,並不能滿足我們快速檢視的需求。我就想在 Android Studio 中看,可以不斷快速的往下跟進。其實我們在下載 sdk 的時候一般都會下載原始碼,只不過剛好 android.jar 包中沒有這個 class 類的原始碼,所以我們才找不到而已。這個時候我們需要一個比較完整的 android.jar ,用來替換我們 sdk 中的 android.jar 檔案,關鍵是這個 jar 怎麼來?最好的方式是自己去編譯,但很多哥們可能覺得自己編譯成本高,那麼我們也可以去 github 上下載。https://github.com/anggrayudi/android-hidden-api 把原來的儲存一份改下命名,把下載的複製進去,然後重啟 Android Studio 再去看看,發現不僅沒有報紅而且可以點選了。
到後面這些還是無法滿足我們的需求,比如現在我們已經把 C++ 進階學完了,我想跟到 native 層的原始碼去看看,比如去看看底層的 Binder 驅動,或者去看看類的載入機制,我再送大家一個連結,裡面所有的原始碼基本都能找到:https://pan.baidu.com/s/1tGtBt5Y1G50yI10EkVRPAw
再囉嗦幾句,如果我們對原始碼非常感興趣,我建議大家還是自己去編譯原始碼,這樣我們就可以利用 Android Studio 去除錯跟蹤原始碼,屢試不爽。
二.前輩力量
文章的開頭有提到,沒有人一上來就可以看得懂原始碼,我們都是從 Hello World 開始的,所以沒有什麼捷徑可以走,無非就是看我們誰花的時間多,誰更願意折騰。別看網上有很多大牛寫了很多分析原始碼的文章,但其實他們都是經過反覆折騰,才能寫出那一篇形如流水卻很抽象的文章。所以我們寫了那麼多分析原始碼的文章,錄了那麼多直播課程,無非就是我們在背後花了很多時間而已。只要你願意我能行的,你也能行。
當然剛一開始我並不建議大家自己去看原始碼,我記得自己第一次看原始碼的時候,點選進去是一臉蒙 B。所以剛一開始我們需要藉助前輩的力量,跟著大牛的思路去看原始碼,也就是大家通常所說的老司機帶帶我。
有幾點需要提醒大家是,有些文章可能篇幅比較長,要有耐心不斷反覆的多看幾遍。當然有時也不必在一棵樹上吊死,其他樹上也可以多試幾次。其次我們找一些稍微靠譜一點的,閱讀量多一些的文章,排版稍微好點,圖文並茂的。最後,不管別人的文章寫得有多好有多清晰多牛掰,始終不是我們自己的,也有可能存在 bug 。這也是我為什麼建議大家看閱讀量稍微高些的文章,因為有問題大家會評論提出來,會經過很多次的修正調整。我們最好自己親身去實踐,自己做做筆記或者寫寫文章,把它真正變成自己的知識,這樣提升的速度是非常快的,屢試不爽。
以下是一些原始碼分析的文章,我們可以選擇性的挑一些啃一啃,如果文章看不太懂還可以看看直播視訊:
- JNI 基礎 - Android 共享記憶體的序列化過程
- 第三方開源庫 Glide - 原始碼分析(補)
- 第三方開源庫 Retrofit - 原始碼設計模式分析
- 第三方開源庫 RxJava - 基本使用和原始碼分析
- 第三方開源庫 EventBus - 原始碼分析和手寫
- Handler通訊 - 原始碼分析和手寫Handler框架
- 編譯時註解 - ButterKnife原始碼分析和手寫
- 原始碼閱讀分析 - Window底層原理與系統架構
- 原始碼閱讀分析 - View的Touch事件分發
- 原始碼解析 - View的繪製流程
- Android外掛化架構 - 攔截Activity的啟動流程繞過AndroidManifest檢測
- Android外掛化架構 - Activity的啟動流程分析
- Android程序間的通訊 - IPC(機制)Binder的原理和原始碼閱讀
- 外掛式換膚框架搭建 - setContentView原始碼閱讀
- 外掛式換膚框架搭建 - 資源載入原始碼分析
- Android無限廣告輪播 - ViewPager原始碼分析
三.慣用套路
每個人閱讀原始碼的思路都會有些不一樣,姿勢也會有所不同,下面我僅代表個人的觀點談談我的慣用套路,假如我們想去分析 glide 這個開源庫,假設現在網上的資料也沒法滿足我們了:
第一步會去畫 UML 時序圖,相信我們在分析 glide 原始碼的時候,剛開始可能連訪問網路的碼頭都找不到。畫時序圖不光能防止我們沉入茫茫大海,還能讓整個載入顯示流程都非常清晰,好記性不如畫流程圖。
第二步會去畫 UML 類圖,每個第三方庫在其架構設計上,都會有其值得借鑑的地方。如 retrofit 這個開源庫,雖然類檔案並不多,但裡面的封裝解耦思想,都能夠在我們實際的開發過程中派上用場。
第三步會去抓細節,比如 glide 怎麼壓縮適配圖片的,快取怎麼處理的,是如何載入 gif 圖片的,怎麼解析視訊封面的。抓細節其實就是帶著問題去看原始碼,我們在開發過程中遇到的很多疑問,原始碼會給我們很多更好的解決方案。
第四步會去參考模仿,並不是建議大家去重複造輪子,比如我們知道了 IOC 的實現原理,就能完美的解決 mvp 中多 prsenter 的情況;清楚了 RxPermission 的實現方式我們就能很輕鬆的寫出類似 RxPay 和 RxShare 等等。
第五步會去反思現有的架構設計,我們在寫專案的時候,往往由於時間的原因,只是考慮了怎麼實現,能實現能按時上線就好。隨著業務的不斷修改增加,可能已經沒有了高蛋白低脂肪。當然隨著經驗的增長考慮的也會多一些,但仍然需要不斷的反思和學習。
四.隨心所欲
當我們閱讀了大量的原始碼和第三方開源庫後,我們就能打通任督二脈,學習的速度會越來越快。當同事遇到一些棘手的 bug ,我們能從原始碼的角度去分析解決;一些難以實現的需求,我們也能很快的找到解決方案。這時我們要麼是在大公司鍍金,要麼是在小公司做負責人,是真正的喜歡工作、學習和折騰。