在長(zhǎng)沙待的那些年,身邊所看到的大概可分為兩類人,一類是不斷反復(fù)的做業(yè)務(wù)邏輯,只求功能能夠?qū)懗鰜?lái),每天重復(fù)上下班,不想過(guò)多的去折騰;還有一類是不斷的反思總結(jié)和學(xué)習(xí),不只停留在做的層次上,是真正的喜歡做這行,且覺(jué)得非常有意思。沒(méi)有什么好與壞,只是大家的追求不同而已。但如果我們想要去大一點(diǎn)的公司,或者找一份工資稍微高些的工作,后面我們就會(huì)有很多坎要去邁,其中一個(gè)就是閱讀源碼,所以這期我們主要來(lái)探討一下閱讀源碼的 一些姿勢(shì)。在真正踏上這條路之前,希望我們能明確以下幾點(diǎn):
沒(méi)有人一上來(lái)就可以看得懂源碼,我們都是從 Hello World 開(kāi)始的,所以沒(méi)有什么捷徑可以走,無(wú)非就是看我們誰(shuí)花的時(shí)間多,誰(shuí)更愿意折騰。
大家都是上下班,為啥別人工資拿得高福利又好,而自己大小周,偶爾還需要加班通宵。同樣三四年別人拿 20k,我自己卻只拿了 10k。注意我說(shuō)的是 20k ,之前寫過(guò)一篇文章 《從3K到30K,23歲的年紀(jì)我到底經(jīng)歷了什么》 這次同樣怕某些哥們會(huì)噴,哪有那么高?我們心中要有美好的信念,要有不斷向上的激情。
能力提升過(guò)程中我們能從中獲得很多東西,內(nèi)心也會(huì)變強(qiáng)大,關(guān)鍵是我們?cè)谧鲰?xiàng)目的時(shí)候,的確會(huì)要順手很多,這就可以拿來(lái)?yè)Q錢和時(shí)間,前提是我們?cè)敢饽脮r(shí)間去換。
一.常用工具
首先來(lái)介紹一些看源碼的工具,第一個(gè)就是我們的開(kāi)發(fā)工具 Android Studio ,這里我們以具體的示例來(lái)說(shuō),假設(shè)現(xiàn)在我想看 setContentView 的源碼,那么我們可以直接跟進(jìn)到源碼的方法里面去:

這時(shí)如果再往里面跟發(fā)現(xiàn)是一個(gè)抽象類,我們必須要找到實(shí)現(xiàn)類,一般來(lái)講我們可以搜索(ctrl + F)找到其創(chuàng)建實(shí)例的地方:

是紅色的,這個(gè)時(shí)候我們?cè)僖矝](méi)法往里面跟了(一碰到紅尷尬癥就犯了,腎得慌),碰到這種情況我們可以試試全局的搜索(雙擊 shift)

但很多情況下我們?nèi)炙阉饕菜阉鞑坏?,接下?lái)給大家介紹第二個(gè)工具,我們可以在線瀏覽源碼閱讀:http://androidxref.com 這里面不光有 Java 層的源代碼還有 native 層的源代碼

在線查看一般都是比較精確要看哪個(gè)類的時(shí)候,并不能滿足我們快速查看的需求。我就想在 Android Studio 中看,可以不斷快速的往下跟進(jìn)。其實(shí)我們?cè)谙螺d sdk 的時(shí)候一般都會(huì)下載源碼,只不過(guò)剛好 android.jar 包中沒(méi)有這個(gè) class 類的源碼,所以我們才找不到而已。這個(gè)時(shí)候我們需要一個(gè)比較完整的 android.jar ,用來(lái)替換我們 sdk 中的 android.jar 文件,關(guān)鍵是這個(gè) jar 怎么來(lái)?最好的方式是自己去編譯,但很多哥們可能覺(jué)得自己編譯成本高,那么我們也可以去 github 上下載。https://github.com/anggrayudi/android-hidden-api 把原來(lái)的保存一份改下命名,把下載的復(fù)制進(jìn)去,然后重啟 Android Studio 再去看看,發(fā)現(xiàn)不僅沒(méi)有報(bào)紅而且可以點(diǎn)擊了。


到后面這些還是無(wú)法滿足我們的需求,比如現(xiàn)在我們已經(jīng)把 C++ 進(jìn)階學(xué)完了,我想跟到 native 層的源碼去看看,比如去看看底層的 Binder 驅(qū)動(dòng),或者去看看類的加載機(jī)制,我再送大家一個(gè)鏈接,里面所有的源碼基本都能找到:https://pan.baidu.com/s/1tGtBt5Y1G50yI10EkVRPAw
再啰嗦幾句,如果我們對(duì)源碼非常感興趣,我建議大家還是自己去編譯源碼,這樣我們就可以利用 Android Studio 去調(diào)試跟蹤源碼,屢試不爽。
二.前輩力量
文章的開(kāi)頭有提到,沒(méi)有人一上來(lái)就可以看得懂源碼,我們都是從 Hello World 開(kāi)始的,所以沒(méi)有什么捷徑可以走,無(wú)非就是看我們誰(shuí)花的時(shí)間多,誰(shuí)更愿意折騰。別看網(wǎng)上有很多大牛寫了很多分析源碼的文章,但其實(shí)他們都是經(jīng)過(guò)反復(fù)折騰,才能寫出那一篇形如流水卻很抽象的文章。所以我們寫了那么多分析源碼的文章,錄了那么多直播課程,無(wú)非就是我們?cè)诒澈蠡撕芏鄷r(shí)間而已。只要你愿意我能行的,你也能行。
當(dāng)然剛一開(kāi)始我并不建議大家自己去看源碼,我記得自己第一次看源碼的時(shí)候,點(diǎn)擊進(jìn)去是一臉蒙 B。所以剛一開(kāi)始我們需要借助前輩的力量,跟著大牛的思路去看源碼,也就是大家通常所說(shuō)的老司機(jī)帶帶我。
有幾點(diǎn)需要提醒大家是,有些文章可能篇幅比較長(zhǎng),要有耐心不斷反復(fù)的多看幾遍。當(dāng)然有時(shí)也不必在一棵樹(shù)上吊死,其他樹(shù)上也可以多試幾次。其次我們找一些稍微靠譜一點(diǎn)的,閱讀量多一些的文章,排版稍微好點(diǎn),圖文并茂的。最后,不管別人的文章寫得有多好有多清晰多牛掰,始終不是我們自己的,也有可能存在 bug 。這也是我為什么建議大家看閱讀量稍微高些的文章,因?yàn)橛袉?wèn)題大家會(huì)評(píng)論提出來(lái),會(huì)經(jīng)過(guò)很多次的修正調(diào)整。我們最好自己親身去實(shí)踐,自己做做筆記或者寫寫文章,把它真正變成自己的知識(shí),這樣提升的速度是非??斓?,屢試不爽。
以下是一些源碼分析的文章,我們可以選擇性的挑一些啃一啃,如果文章看不太懂還可以看看直播視頻:
- JNI 基礎(chǔ) - Android 共享內(nèi)存的序列化過(guò)程
- 第三方開(kāi)源庫(kù) Glide - 源碼分析(補(bǔ))
- 第三方開(kāi)源庫(kù) Retrofit - 源碼設(shè)計(jì)模式分析
- 第三方開(kāi)源庫(kù) RxJava - 基本使用和源碼分析
- 第三方開(kāi)源庫(kù) EventBus - 源碼分析和手寫
- Handler通信 - 源碼分析和手寫Handler框架
- 編譯時(shí)注解 - ButterKnife源碼分析和手寫
- 源碼閱讀分析 - Window底層原理與系統(tǒng)架構(gòu)
- 源碼閱讀分析 - View的Touch事件分發(fā)
- 源碼解析 - View的繪制流程
- Android插件化架構(gòu) - 攔截Activity的啟動(dòng)流程繞過(guò)AndroidManifest檢測(cè)
- Android插件化架構(gòu) - Activity的啟動(dòng)流程分析
- Android進(jìn)程間的通信 - IPC(機(jī)制)Binder的原理和源碼閱讀
- 插件式換膚框架搭建 - setContentView源碼閱讀
- 插件式換膚框架搭建 - 資源加載源碼分析
- Android無(wú)限廣告輪播 - ViewPager源碼分析
三.慣用套路
每個(gè)人閱讀源碼的思路都會(huì)有些不一樣,姿勢(shì)也會(huì)有所不同,下面我僅代表個(gè)人的觀點(diǎn)談?wù)勎业膽T用套路,假如我們想去分析 glide 這個(gè)開(kāi)源庫(kù),假設(shè)現(xiàn)在網(wǎng)上的資料也沒(méi)法滿足我們了:
第一步會(huì)去畫 UML 時(shí)序圖,相信我們?cè)诜治?glide 源碼的時(shí)候,剛開(kāi)始可能連訪問(wèn)網(wǎng)絡(luò)的碼頭都找不到。畫時(shí)序圖不光能防止我們沉入茫茫大海,還能讓整個(gè)加載顯示流程都非常清晰,好記性不如畫流程圖。
第二步會(huì)去畫 UML 類圖,每個(gè)第三方庫(kù)在其架構(gòu)設(shè)計(jì)上,都會(huì)有其值得借鑒的地方。如 retrofit 這個(gè)開(kāi)源庫(kù),雖然類文件并不多,但里面的封裝解耦思想,都能夠在我們實(shí)際的開(kāi)發(fā)過(guò)程中派上用場(chǎng)。
第三步會(huì)去抓細(xì)節(jié),比如 glide 怎么壓縮適配圖片的,緩存怎么處理的,是如何加載 gif 圖片的,怎么解析視頻封面的。抓細(xì)節(jié)其實(shí)就是帶著問(wèn)題去看源碼,我們?cè)陂_(kāi)發(fā)過(guò)程中遇到的很多疑問(wèn),源碼會(huì)給我們很多更好的解決方案。
第四步會(huì)去參考模仿,并不是建議大家去重復(fù)造輪子,比如我們知道了 IOC 的實(shí)現(xiàn)原理,就能完美的解決 mvp 中多 prsenter 的情況;清楚了 RxPermission 的實(shí)現(xiàn)方式我們就能很輕松的寫出類似 RxPay 和 RxShare 等等。
第五步會(huì)去反思現(xiàn)有的架構(gòu)設(shè)計(jì),我們?cè)趯戫?xiàng)目的時(shí)候,往往由于時(shí)間的原因,只是考慮了怎么實(shí)現(xiàn),能實(shí)現(xiàn)能按時(shí)上線就好。隨著業(yè)務(wù)的不斷修改增加,可能已經(jīng)沒(méi)有了高蛋白低脂肪。當(dāng)然隨著經(jīng)驗(yàn)的增長(zhǎng)考慮的也會(huì)多一些,但仍然需要不斷的反思和學(xué)習(xí)。
四.隨心所欲
當(dāng)我們閱讀了大量的源碼和第三方開(kāi)源庫(kù)后,我們就能打通任督二脈,學(xué)習(xí)的速度會(huì)越來(lái)越快。當(dāng)同事遇到一些棘手的 bug ,我們能從源碼的角度去分析解決;一些難以實(shí)現(xiàn)的需求,我們也能很快的找到解決方案。這時(shí)我們要么是在大公司鍍金,要么是在小公司做負(fù)責(zé)人,是真正的喜歡工作、學(xué)習(xí)和折騰。