閱讀項目源碼時,一看到一大堆的類就頭暈怎麼辦?

〖注:是app項目源碼不是系統源碼〗

我是個android新手,水平大概是能做簡單的app,因此想學習更複雜點的東西,於是乎下載了很多人推薦的開源項目比如eoe客戶端,四次元客戶端。但是打開源碼看到那麼多文件夾、那麼多類我就被嚇到了,退縮了。請問是我的水平還不能閱讀嗎?如果是,那麼我該學習什麼?如果不是,有什麼好的方法來閱讀?


要善於使用工具。

IDE+靜態語言不是擺樣子的,不要用成記事本+動態語言,例如多Find Usages。

此外,邊看邊猜邊改邊試驗邊記錄一些東西,都對讀代碼有幫助。


首先編輯器很重要,推薦使用 AndroidStudio. 四次元客戶端也是用 AndroidStudio 完成的,用 AndroidStudio 導入項目會比 Eclipse 容易一些。

閱讀代碼的話,建議從 manifest.xml 文件讀起,找到 MainActivity (可能不叫這個名字)

可能是在 && 標籤下有如下 intent-filter 的 Activity

&
&

找到 MainActivity 後,看下 MainActivity 是否繼承自某個基本的Activity (BaseActivity) ,如果繼承了其他 Activity ,從繼承的 Activity 讀起,如過沒有 BaseActivity ,則找到 MainActivity 對應的 layout 文件,layout 和 activity 互相對照看,利用 IDE 可以找到當前類中使用的其他類的方法,一點一點擴展。

比如閱讀 Activity ,一般都是在 Activity 的 onCreate() 方法初始化各個視圖 findViewById(),然後給對應的視圖填充數據 view.setText("xxx") 或者添加適配器 listView.setAdapter(new ListAdapter()); 。

----------------- 4.12 補充 ------------------

個人經驗,如果在對照著源碼敲時,如果暫時不能理解某個方法時,先把那個方法跳過,按照調用的順序依次添加方法,這樣會幫你按照作者的思路完成代碼,讓你理解更深刻。至於現在不理解的方法,在接下來的代碼中一定會去調用,在那時對這個方法多加註意,這樣對不理解的代碼也會加深印象。

----------------- 再次補充 ------------------

上面我提到 onCreate() 方法,其實只是比較簡單的針對 Activity ,如果需要閱讀的是 Fragment 或者 各種自定義視圖的話,比較好的辦法是根據視圖的生命周期(如果不了解視圖的生命周期,各個搜索引擎上一搜一大把)閱讀,代碼一般都是遵循在不同生命周期完成不同任務的,所以按照生命周期閱讀也會讓你更容易理解代碼的作用。


我個人拿到一個陌生項目,分析源碼主要步驟如下:

1、根據項目介紹,找到應用程序入口(類似各種語言入門教程都有的main函數),運行一遍,跑起來狀壯膽;

2、通過工具(IDE)打開看項目主體目錄結構,根據命名猜測開發者的分層思路,如果沒有明顯分層,則看文件目錄;

3、按分層(目錄)找介面,根據介面(和介面注釋)猜測功能;

4、根據介面找到具體實現,看具體實現的源碼,分析開發者的設計和實現細節;

5、等差不多熟悉主要函數和模塊幹什麼事情了,再看項目的單元測試,甚至自己可以動手驗證

注意,通常3和4這裡會非常耗時,要耐心,第一遍可以泛讀,然後循環精讀,必要時你可能需要做筆記,也可以寫博客分析看代碼體會心得,如果實在不懂,可以調試或者直接跳過。

這樣,一步一步從點到線,由線到面,循序漸進,當你真正理解了開發者的主要開發思路,知道了主要功能模塊的實現原理,最終梳理透了一個項目源碼,那種成就感不亞於自己獨立開發一個項目。


我是一個剛開始學游泳的新人,一站到泳池邊,看到那麼多的水就嚇到了,頭暈了。請問是因為我游泳的水平不夠嗎?如果是,我應該如何學習?如果不是,我應該如何姿勢優雅的游泳?

教練一言不發,從後面一腳把你踹到池子里去……


這是正常的現象,剛開始接觸任何東西的時候,大腦都情不自禁地抵觸這玩意。我覺得這肯能是人類作為一種生物進化的結果,大腦避免讓自己更勞累,消耗更多能量。

但是人類不僅僅是一種簡單的生物,我們有長期目標,我們要和短期的阻力做抗衡。

我也經常遇到這種情況,唯一的辦法是,沉下心仔細地閱讀文檔。把項目里的各種readme,wikipage, getting started等等都通讀幾遍,注意不是一遍,是*幾遍*直到你能夠理解其內容,建立大概的聯繫為止。

然後把項目導入到IDE(我一般用eclipse),+ maven, maven生成eclipse project的命令是:

mvn eclipse:eclipse

然後你可以嘗試run一下這段代碼,如果這塊代碼不能run起來,說明Owner沒有很好地維護它。我覺得一個好項目最重要地是有完善的文檔,可以輕易地run起來。

當你可以看到項目的效果你就可以開始學習他了。其實經過剛才那些過程你已經學習了好多了。

然後你就可以深入到代碼內部,去看你感興趣的部分,但是光看是沒用的,你得去改他的代碼,去實現一些新feature,其中你肯定會遇到很多問題。

就用Stack Overflow或者google去查詢遇到的問題,*千萬別用Baidu*,98%的情況下,你應該會查到它的解決方法。

實在沒有,你就可以去Stack Overflow上面提問題了,可以和熱心的幫助者討論,最後如果問題解決了不要忘記,標記成推薦答案和upvote。

最後別忘了在https://github.com上fork這個項目,pull request你覺得有用的升級和改動。

當你做到這一切,有一天你一定會覺得當時一大堆的代碼,變得清晰又簡單的。


使勁看,熟到看代碼像看小說一樣。就不暈了。

另外,善用IDE,對代碼做好著色和排版。

還有一種方法,給代碼加中文注釋。一行一行的加。


猛讀 狠讀 等你讀通一個10w行代碼的項目 遇到5w行的就很easy了,反之 如果你只搞通過5w行的 要你弄一個10w行的 自然很吃力


debug


正常

先看outline

然後試試debug,trace進去比較清晰


單純看代碼沒意義,對項目代碼的理解一般遵循這幾步:一、對採用開發框架的文件結構、邏輯組織結構的理解;二、對業務邏輯的理解,就是去了解這塊兒代碼是做什麼的,正向的去看,如果讓你寫,你會怎樣寫,然後對比別人的實現方式;三、代碼細節看正常實現過程中有哪些細節,哪些坑,並怎麼解決的。


個人水平基本寫不出app,閱讀源碼是根據想要了解的功能去看的。個人經驗,閱讀源碼先不要求全,帶著相對簡單的目的分小模塊去看,這樣會有較大的收穫。

比如你想做清理功能,那就先找找清理功能對應哪些模塊,再將模塊細分,比如磁碟空間,mediastore等。一個功能一個功能的消化,積少就成多了。


iOS開發,同樣喜歡github讀開源代碼。

自己讀得方法就是先把項目運行一遍,然後找到自己感興趣的模塊,去找到相關模塊的代碼去讀,而不是通讀。


至少搞明白這源碼是幹嘛的再去看吧!看代碼去猜它幹嘛的,也需要有背景吧!


1.看什麼項目

看源碼,如果目錄組織不清晰,文檔不齊,代碼結構混亂的,就不要去讀了。你要是想看源碼,請找有幾大基金會組織或者大公司背景的開源項目。

2.背景知識

如果沒學過計算機圖形學,那麼肯定看不懂渲染引擎,沒學過編譯原理,肯定看不懂編譯器。核心代碼都是有理論支撐的。這也可以幫助你從大量源代碼文件中,找出你需要的部分,而不是耗費在無用的地方。

3.一個強大的工具

IDE 是免不了的了,包括但不限於,某個函數在何處被調用,某個介面的實現類有多少個等等。用於迅速組織起作者在編寫代碼時的習慣和個人風格,有助於快速推導出作者的意圖。


你需要在電腦上安裝一款uml工具,然後對著源碼把類的靜態關係畫出來。然後再照著源碼把主要流程畫出動態時序圖,一份代碼就基本理解了。


如果能和作者聯繫,或者能看到作者的說明文檔,可以獲得一些關於代碼基本結構和主要類的知識。

如果得不到這類額外信息,那就只能用下面的方法了。我前幾周首次摸索出來,並實際用於閱讀一份作者早就離職,變數名函數名混亂,函數長度普遍300+行的純C代碼。拋磚引玉。適用於環境條件不允許一邊運行一邊debug的代碼,也就是靜態代碼的閱讀

步驟:

  1. 泛泛地知道這個項目是幹什麼用的(下載/網路爬蟲/文本處理等)

  2. 知道這個項目的輸入:內容(數據表示什麼意思)、格式(圖片/文本/XML/EXCEL等)、方式(硬碟文件/網路通信/FTP下載/HTTP訪問等)。
  3. 知道這個項目的輸出:內容、格式、方式(UI界面/硬碟文件/網路通信)。
  4. 從輸入點開始追蹤信息流,直到輸出端。即,數據在什麼類的什麼方法輸入,保存在哪些變數里,然後被用於計算出了什麼結果,結果又被保存在哪些變數里……
  5. 追蹤信息流的時候對每一個函數都要分析出這個函數對傳入的參數做了什麼,返回了什麼。有些代碼寫得差的,可能函數有幾百行上千行,此時要自己主動對代碼進行分段,分段方法:每次看一行。如果一行里好多嵌套函數,就看一行中的某一段。看懂了某一段再看下一段,直到這一行看完。然後嘗試用一句話來記錄這一行乾的事:XXXX/XXX/XXX.cpp,Line 3212-3213,對傳入的XXX、XXX和XXX進行了XXXX,返回XXX。如果能看懂每一行,總是能歸納出哪幾行的功能相對單一的。於是看懂了這一段,做筆記。如果能看懂每一段,就能看懂整個函數,然後針對函數做筆記。基本上就是這樣自下而上地歸納代碼功能(還原論)。

補充說明:

  • 對於規定變數必須定義在函數開頭的語言(比如C),變數的值在特定行是什麼判斷起來並不容易。此時只能從函數第一行開始,記筆記來追究變數值的變化。
  • 對於面向對象的代碼,一個虛函數被調用時,判斷其到底是哪個具體類的函數是一項比較困難的工作。此時要針對這個被調用的函數所屬的對象進行追根溯源的追蹤。
  • 有些寫得爛的代碼愛用莫名其妙的i、j、k、a作為標記位變數,比如要不要break、要不要continue之類,此時只能自己在筆記上時刻記錄變數的值,然後看代碼怎麼使用這些變數的值,來推測變數的含義。
  • 對於全局變數和多線程程序,追蹤變數到底在哪些地方被更改是個挺麻煩的事情。此時還是先針對每一個線程進行分析。Visual Studio、Source Insight的查找引用的功能可以讓你找到所有會修改該函數的代碼,從而讓你判斷這個變數是否被其他線程修改了。
  • 做筆記的方法:我為每一個函數(線程函數也是函數)建了個txt文件,文件名就是函數名。文件內容是逐行分析函數的功能,然後在文件的最前面幾行,用一句話描述這個函數做了什麼。這很重要,因為閱讀後續代碼時,如果看到代碼調用了你讀過的函數,你會很需要瞬間看懂該子函數的功能,否則調用者函數代碼的閱讀過程會被打斷。

  • 這類代碼的閱讀比較痛苦,會持續好多天,有些時候容易忘記看到哪兒。我的做法是先在一個Excel文件出所有線程函數,第一列是函數名,第二列是函數的總行數,第三列是目前讀到第幾行。然後一個函數一個函數看。如果線程函數調用了子函數,那就暫停線程函數的閱讀,在Excel里用顏色標記處這個函數是「讀了一半的」,然後在Excel里新增一行那個被調用的子函數,同時在硬碟上新增一個用該子函數的函數名命名的txt文件,開始閱讀子函數。關於顏色標記,我的習慣是從未讀過的函數用紅色,正在讀的用黃色,讀完的用綠色(現在Excel應該都有快捷設置這三種單元格顏色的按鈕了吧)。
  • 不要偷懶,堅持下去,走一步再走一步,看著自己讀完的函數、記錄函數的筆記文件越來越多,直到所有代碼都讀完為止。那一刻成就感簡直爆表。

推薦工具:

  • Source Insight(看代碼)

  • Notepad++(做筆記)

  • Excel(列出所有函數名)


請告訴我標題不是「一看到一大堆的糞」


現在的APP要研究就分兩塊吧,UI相關和公用的業務相關。

業務呢,一般就是寫orm,http請求,event bus之類的。這些一般是個框架,能找設計模式去套的話就比較好理解,不過客戶端大多用的別人開源的。這個讀源碼的時候看看怎麼用的就行,這類框架建議單獨去閱讀。

UI方面就按activity去看就行了。


大哥,你安卓Java居然敢說就暈了,你的前途堪憂呀,我做c開發和彙編語言開發,給硬體寫驅動,看晶元的電路圖,給你看的話,你應該會直接掛了。


以個人經驗,我經常拿到一個項目源碼時會先導入到Ide中,然後解決掉sdk和路徑等問題,於是第一步開始編譯該項目,用手機或虛擬機調試,成功後:

第一步:看編譯後的apk,從頭到尾用一遍,然後基本上能知道該apk有哪些頁面,有哪些功能等。

第二步:打開源碼,看項目結構,一般在src裡面,都是分層結構,比如activity的包裡面一般都是活動控制的代碼,util的包裡面基本上都是一些格式轉換什麼的。其實包的命名不同項目之間都大同小異。看的多了就明白每個包是幹嘛的了。看完src後就打開res文件,對自己感興趣的layout.xml看一遍,然後針對每一個xml去看對應的activity。在activity.java裡面基本能看出每個步驟是怎麼做的。這樣就可以看到一些網路控制類,實體類等等。

第三步:如果覺得理解了某一個地方,可以改源碼,然後編譯調試看是否達到自己預期的結果。或者加上一些日誌輸出,看是否是自己想像的那樣輸出的。

多看項目源碼,會對自己的技術有很大幫助的。


推薦閱讀:

有哪些優秀的 Android 應用開源項目、特效、設計資料推薦?
Android 應用開發一般都哪個版本的 SDK ?
對於一個Android 第三方庫源碼或Android 應用框架層源碼時,怎樣才能更有效的閱讀和理解?
國外有哪些關於Android的學習網站或資料或論壇?
有必要研究安卓源碼嗎?

TAG:互聯網 | 程序員 | Android開發 | Android |