Android Framework 如何學習,如何從應用深入到Framework?

看了深入理解安卓1,看到第7章,看了安卓源碼情景分析,看到日誌那章,還看了一點安卓內核剖析,看著看著就看不動了,現在又拐回來看應用,關於系統方面的書前面講原理的比較多,以至於工作中感覺接觸到AMS,PMS,電源服務還沒看到,就不想看了,我還沒有跳讀的習慣,每本書都想從頭看到尾,但又限於水平有限,很多都不能充分理解,看著看著就看不動了,應用的層的書籍又很少涉及Framework方面的知識,就感覺應用的時候實現難度還不大,一到修改系統方面知識的時候就感覺難度很大,方法調用的跨度太大,一些界面實現管理跟應用差別很大,就想問下怎麼才能找到正確的入門方向?

----------------------------

9.20號更新一下。

深入理解安卓卷1沒有必要看完,看下1到6,9和10就行了,也可直接看卷2和卷3.


猶豫了整整兩天要不要寫這個回答,結果看到500+的關注,只有寥寥15個回答,覺得還是分享一下自己覺得高效又無痛的方法罷。( 最高票的@Groffa 先生總結非常到位,觀點本身沒什麼問題,但觀點的展開有點潦草)

首先放個地圖炮,任何光講源碼的書都是耍流氓,無一例外。作者或許是大神,或許對於每一個地方的每一處源碼都爛熟於心,但並不代表他們可以寫出一部好書。原因很多時候在於,Android的功夫,在Android之外。這是理解Android源碼的「道」,也是我近幾年來愈發強烈的感受。

至於「術」,我只想說大神博客也好,書也好,90%的講述方式都是錯誤的——作者展示出Android源碼,然後告訴你這段是幹嘛的,然後下一段……這樣的書或博客,我個人看得非常痛苦,一開始我不明白為什麼,工作了第三年,猛然明白,讀起來痛苦的原因是倒轉了因果。

幾乎所有代碼or模塊or系統的開發初衷,都是為了解決某一問題。如果你光看源碼,哦這個是幹嘛的,那裡調用了哪個API,這樣看毫無意義,這樣的所謂「講解」書也毫無意義。大把的《深入XXX》實際上都沒有深入,因為他們並沒有搞清或說清,這裡有個什麼樣的問題,而這個部分模塊or源碼怎樣解決了這個問題,以及曾經其餘的系統上如何解決這個問題——更有甚者,他們講完解決方案,然後再編個問題出來,且說的好像這個問題只有這唯一一種方案可解一樣……

就比如題主和很多答主提到的Binder機制,所有人都能說出來它是跨進程通信用的,可是你依然會看得想要吐血。包括很多blog講起這部分,都有一種先有答案後編個問題出來的嫌疑,理解並不深入(尤其是上來就將Media部分的,大部分根本只講了「怎麼用」,完全沒有「為什麼」的部分,這也好意思起名字叫「深入理解XXX」)。

你想搞明白,首先要忘了Binder。然後想想看,有什麼樣的方案實現一個跨進程通信的方式?最容易想到的,一個是「共享內存」的方式或是「共享磁碟文件」的方式。其餘的方式呢?

想不到去看看舊有的Linux系統上的演變過程,當你看到管道(Pipe)方式的實現,就會開始恍然大悟——原來還可以通過這樣。然後你會更加理解UDS(Unix Domain Socket,非TCP/IP裡面的那個socket,很多人會困惑與此)的出現,此刻你心裡對於Server-Client端互相建立起IPC鏈接的過程才將變得明朗,甚至可以推出RPC(Remote Procedure Calls)的實現模型。

到這裡,你再去看Binder的實現,從宏觀的模型開始,一切都變得異常清晰起來。對於Binder Client和Binder Service各自的角色有了理解,Binder驅動與ServiceManager的聯動,就變得更加清楚——和UDS或者RPC是不是很類似?甚至更容易理解一些,如果更加抽象的形容,ServiceManager就像DNS一樣,負責Client查詢到BinderService的IP地址(這也就理解了為何ServiceManager的通信標誌恆為0),而Binder驅動則是路由器的角色。

然後細化下去,針對每一個模塊本身的職責,詢問更細節的實現,永遠記住,先有的問題,之後才有的代碼——這樣才能理解為何Parcel是必要的(跨進程通信的高效序列化數據載體),為何IBinder或BpBinder是必須的,AIDL又是什麼用——代碼實現是新鮮的,但是有了之前的鋪墊和對問題的預期,它們的出現才是可理解的。這是理解Android源碼之「術」。

當然,說起來容易,做起來難

整套模塊看下來,拋開信息檢索能力不談,你需要補一些C++的基礎,需要補計算機系統的基礎,甚至需要理解設計模式——但不是說你成為任何一方的專家才能理解,只是隨著一點點深入問題,隨時去補課罷了。所以說跳著看書的能力是必須的,不是你想不想或者喜不喜歡的問題,它就是必須的——你唯一的問題就是願不願意讓自己適應它,還是找個借口繞路。

所以這個問題又回到了最初提出的觀點——Android的功夫,在Android之外。你要想「理解」而非單純的「知道」,想「學習」而非單純的「記誦」,我覺得沒有他路可走。

總結起來就是:

  • 先理解模塊對應的要解決的「問題」是什麼,再去給問題找解決方案的思路去理解源碼。
  • 理解源碼的功夫不止在Android本身,也要提高Android之外的姿勢水平。

最後,繼續鄙視那些玩了幾個app、聽說Android開發語言用Java就對Android嗤之以鼻的自大狂們——對於Android這個龐大的知識庫來說,90%的人離入門都還差得遠呢。


工作中很多任務是要去定製Framework,但是還是很多不會的,不過我可以告訴你如何去摸索。在此拋磚引玉一下。

Framework這個東西挺好挺大的,不過它的核心其實也好說。一是承上啟下提供應用的API,一是提供操作系統的服務。

相信所有人開始學習android開發的時候都是從以下這張圖開始的,framework位於hal、系統庫之上,位於app之下。

Framework同下層打交到的方式就是jni,同上層打交到的方式就是抽象出各種java介面,在開發app的時候,import的各種android.* 就是各位在查文檔時候的東東了。

像題主這樣從app而來想要學習framework的肯定對JNI不那麼熟悉吧,沒關係,Google的命名方式可以讓你忽略這部分實現,好好看java代碼就夠了。

從哪裡開始呢?上面那張結構圖裡面的各種Manager背後都是系統服務,Framework包含各種系統服務,所以「得服務者、得Framework」(我瞎說的,哈哈哈),這裡可以簡單介紹一下這些服務的結構。

Framework里的服務按照「SystemService.java」里分的話,分為可以Binder的服務、LocalService兩類,如下圖所示:

每類服務都會在Systemserver.java里啟動自己,然後其他服務就可以調用了。而且大部分服務都有一個Manager(就是結構圖裡的各種*Manager),這點在搜代碼的時候會看到各種*ServiceManager.java的類。這裡Managers很大一部分都是開放出來的調用介面。

來看看SystemServer.java這個文件的一些函數,如下圖:

在這裡啟動了各種類型的服務,下面這些都很熟悉吧?

這樣是不是找到了各個Service的啟動位置了。就是在這裡,各個服務完成初始化,被調用了構造函數,以及最初被調用的那幾個函數找到了。程序入口找到了,是不是可以解決一半問題了呢?

以上這些都是很長的文件,看起來頭暈有木有啊。這裡推薦一個Framework里最簡單的Service——LightService,一共就以下幾個文件。

./services/core/java/com/android/server/lights/LightsManager.java

./services/core/java/com/android/server/lights/Light.java

./services/core/java/com/android/server/lights/LightsService.java

這個就是控制一閃一閃LED的控制介面了。每個代碼不超過百行,但是也代表了一共典型的Service在Framework裡面是種怎樣的存在吧。

至於你的那些問題,就是要跟著函數調用慢慢走,慢慢看吧。

學習程序最需要會的一點就是--抽象。不管是寫還是看。

寫的抽象不必說。

看的抽象是啥玩意兒?

就是開始看的時候要忽略細節,跟著流程走。工作原理一般都可以文字描述,如何實現的,跟著函數調用一步一步套,流程通了,細節就不在話下了。

如果一開始就糾結各種變數、各種函數名、各種模式,估計會迷路吧。

祝學習進步吧。


謝邀,不太贊同最高票的答案。

Android的功夫,在Android之外。

這句話我很認同,Android Framework只不過是對底層系統的封裝,要想深入理解它,必須熟悉JNI、讀得懂C++、理解Java虛擬機、Linux系統甚至彙編、指令集等等。但是,這並不意味著想要理解Android Framework就必須熟悉這些東西!逆命題與原命題並不是等價的。等你學完上述那些知識,Android說不定已經黃了(當然如果你真的掌握了這些,下一代操作系統是什麼已經不重要了)舉個例子,回想一下你小時候學習說話的時候,大人教你會先教你語法嗎?我可以肯定世界上所有的語言教育都不會這麼做,大家都是先教你喊爸爸媽媽,進而一些簡單的辭彙,然後一些簡單的句子,等你都熟練了,再讓你學習語法,一樣的道理。對於一個有一定語言知識的人,也是一樣,你學英語的時候,也是先學習how are you, I am fine, thank you的吧?如果一個領域對你來說是全新的,你就硬著頭皮去打基礎,有了一定的認知,再去通過你的元認知能力去深入學習。所以,我覺得不要等到萬事俱備的時候才去做某一件事,一旦決定去做,天亮就出發。

另外,我不覺得那些講源碼的書有多爛;要想搞清楚一個系統的構架、設計以及當時碰到的問題以及做出的抉擇,恐怕只有系統的設計者才能講的清楚;據我所知,按照這個觀點只有《C++的設計與演化》才能算得上所謂的「好書」。那些寫書寫博客的人,作為傳經佈道者,很有可能也無法理解某些設計——很多抉擇都是處於當時的特殊場景以及歷史原因;但是這並不妨礙他們給你講解這方面的知識。在看《深入理解XXX》這種書的時候,我有兩個經驗:

  1. 不要記那些所謂的API調用鏈,哪裡調用了哪裡,又從哪裡跳轉到了哪裡;根本沒用,而且你也記不住。你要思考以及關心的是,作者是怎麼跟蹤調用的?一個上千行的函數體,作者是如何知道哪裡是下一個關鍵入口的?比如從Java的native函數,如何找到正確的C++實現?一個Binder Client的調用,怎麼知道他的Server在哪裡?然後你自己可以嘗試跟蹤一下,看看自己會不會跟丟;如果你可以做到,那麼你差不多就可以自己分析源碼了。
  2. 既然你記不住細節,那麼你就需要理解,需要思考;想一想這裡為什麼這麼做,這樣實現是優雅還是謬誤,如果是你,你怎麼做?當然,並不是所有的地方都需要這樣,那些沒有味道的代碼,還是略過吧。把它當作參考書;自己理解一遍之後,再碰到這種問題,直接翻書,不要自己跟了浪費時間。

簡單總結一下就是,看那些講源碼的書或者博客的時候,除非你要了解某個細節,那麼不要過於關心那些複雜的函數調用鏈,學習跟蹤方法以及把握整理流程最為重要。Android源碼樹異常龐大,如果你想一行不漏地看,不可能;就算你這麼幹了,效果也不見得好——只見樹木,不見森林。打個簡單的比方,Activity的啟動流程,你不用關心在AMS裡面這裡跳到那裡是幹什麼,還有ActivityStack以及它的那個SuperXX跳來跳去是在搞毛,你需要了解的是:在Context裡面,通過AMS的Client ActivityManagerNative發起Binder調用進入system_server進程,在AMS裡面繞了一圈(處理Activity棧以及生命周期相關),然後通過IApplicationThread這個Binder調用回到App進程的Binder線程池,在線程池裡面通過Handler發送Message到App主線程,最終通過ClassLoader載入Activity類,創建對象,回調對應的生命周期,整個過程結束。

作為一個過來人,我很認同 @Van Bruce Android的功力在Android之外這個觀點;同時作為一個初學者,我也相信,要了解Android Framework也沒有想像中的那麼難。

扯了這麼多,來正面回答一下這個問題吧。

先糾正題主幾個錯誤:

1. 「沒有跳讀的習慣,每本書都想從頭看到尾」這個是絕對錯誤的,技術書與文學等其它類別的書籍不同,你沒有必要每一章都看,必須糾正這個習慣。第一,不是所有的書每一章每一節每一段每一句都是精華,花時間去看那些價值不大的,就是浪費時間;而且,越到後面,你需要掌握的知識以及要看的書也越來越多,個人壓根兒沒有精力也不可能全部看完;挑一些重點的,自己感興趣的看就可以了,如果你不知道什麼是重點,向前輩請教或者來知乎這種地方提問就行。

2. 「很多都不能充分理解,看著看著就看不動了」,這個也是不對的。沒有人能夠一看就懂,一學就會。都是一點點理解、摸索然後再融會貫通的;一次不理解沒有關係,多看幾次,慢慢就有感覺了。猶記得我當初不理解Binder,老羅的博客,《Binder設計與實現》還有源代碼,我前前後後完整地看了不下六遍;熟能生巧,如果你能把書中看到的,自己思考的,源碼裡面學到的這些散落的東西連成串,有了自己感覺,那麼前面就是通途了。

-------------------------------手動分割-------------------------------------

如何學習Android Framework?路只有一條:Read the f*cking source code。至於如何「平穩」過渡,其實我覺得學習曲線並沒有那麼陡峭——Android Framework的代碼不也是代碼?不理解是因為沒有整體把握而已。

不論是看書,看博客,你的最終目的只有一個「學會看源碼」,而不是「學會源碼」。關於如何閱讀源碼,這不是一個簡單的問題,我有幾點經驗:

  1. 看不懂的多讀。上面已經說過了,沒有人一學就會;特別是對於初學者,你剛看系統源碼,肯定一頭霧水;萬事開頭難,在你覺得艱深晦澀的時候,你就當在背課文;Android Framework的代碼時遵循一定規範的,你在背了一篇課文之後,再去讀別的課文,讀到一半的時候就算你看不懂,很有可能你就會知道下面要講什麼了,雖然下面要講的你也不懂。背熟了之後,你就可以想每一句是什麼意思了;而這裡面的「段落」、「句子」不就是普通的代碼嗎?就這樣,一步一步串聯起來,聚沙成塔,積少成多,就水到渠成了。「書讀百遍,其義自現」講的就是這道理。如果你真的想要學習Framework,一定要多讀,硬著頭皮讀,不要放棄,否則都是扯淡。
  2. 不重要的少讀。看不懂的很容易知道是什麼,那麼怎麼知道哪些代碼是不重要的呢?這裡有兩層意思:其一,強調的是大局觀,在初學習一個模塊的時候,你需要先把握整體,再了解局部;這個場景下,所有的細節都是不重要的。其二,那些真正不重要的邏輯;你剛學習的時候肯定沒有辦法知道哪些是影響不大的邏輯,所以你需要跟著書籍,博客,讓前人帶路;如果跟著它們的腳步走通了這條路,那你就自己獨立走一遍,這時候你肯定會走丟,然後你跟蹤、嘗試,接著到達終點;這時候你自然就知道,哪些重要,哪些不重要。
  3. 邊讀邊思考。學而不思則罔,思而不學則怠。帶著問題去閱讀源碼,這裡是什麼意思?為什麼需要這麼做?這樣的實現是優雅還是俗套?有沒有更好的實現辦法?如果我來寫,我會怎麼寫?諸如此類,有了思考就有了自己的理解。
  4. 不是所有的都需要思考。接上條,Framework的代碼也是人寫的,有精華,自然有糟粕,也有食之無味的。你不用對著每一段代碼都問個十萬個為什麼。一個問題通常有很多種解決方案,當時的設計者選擇目前這種實現,有兼容問題有歷史原因,還有它自己的理解;不是所有的實現在現在看來都是很好的實現,所以,追問這些問題很多時候都沒有意義,不要過度解讀。舉個例子,Android的IPC機製為什麼用Binder?也許有人說,Socket不安全,效率不夠高;共享內存使用不方便,等等。但是你去看看這個問題:為什麼 Android 要採用 Binder 作為 IPC 機制? - Android 開發 你就知道,很多時候並沒有那麼多為什麼。
  5. 記得做筆記。做筆記的重要性在於,它可以記下你自己在某個階段自己的理解,當你更進一步的時候回頭再看當初的理解,想想哪裡是對的,哪裡又有問題,這是一個相當有意思的過程。我想每一個人在看自己之前寫的代碼,都會有在某個地方覺得自己是沙比的時候。根據你學習過程簡單總結一下,這樣你的元認知能力就得到了提升。

最後自薦一下我的博客:Weishu"s Notes 裡面有我對於Binder以及Framework的理解和學習過程,一定會有幫助 ^_^ 至於其它細節問題,可以參考一下我其他的答案。

最後,文明交流,拒絕撕逼。


做過三年framework,自身總結了一套學習方法,大致如下三點。勤加練習,一般性模塊可以看的非常快。

1、高度抽象,構建框架

2、重要函數,深究細節

3、善用工具,及時總結

下班再補充具體細節~

----------------

5月29更新

非常抱歉拖了這麼久,真的比較忙。。。

Android源碼非常龐大,但設計很精妙。縱向分層,橫向模塊化,使得整個源碼更易更新和維護。在手機廠商做framework的更傾向於說自己是做Android系統的,維護的模塊主要包括ActivityManagerService、WindowManagerService、PackageManagerService、PowerManagerService、SurfaceFlinger、通信模塊、多媒體模塊等。Android系統良好的模塊化設計使得各個模塊負責人只需搞懂自己的模塊就可以勝任工作。但是搞定自己的模塊並不那麼容易,對於新人一般要大概做半年才能掌握其精要,有的做了一年發現還有很多點沒有掌握,這也是很常見的。

對於應用開發者來說,他們並不需要修改系統代碼,學習framework只是為了了解並理解某個API調用底層的運行機制,要學到這個深度級別還是比較容易的。

首先必須了解一些背景知識。1??Android系統採用C/S架構;2??絕大部分IPC通信採用Binder通信;3??核心Service大多運行在System_server進程;4??核心Service代碼大部分都在frameworks/base/services目錄下;⑤別一上來就看Binder!!!6??別一開始看源碼就鑽牛角尖!!!

以下便是我的學習方法,不保證適合其他人,供參考。

首先,大概了解下該Service是幹什麼的。我會搜一些好的分析文章收藏起來,大概瀏覽下該Service為上層應用提供了什麼功能?(這些文章並不會去挨個讀,這跟絕大多數人習慣不一樣,他們一般是一邊看分析文章一邊看源碼)。在源碼里找到源碼文件,大概看下核心幾個文件開頭的注釋,注釋一般會說的非常清楚這個是幹嘛的。(我用source insight看源碼)

然後,可以嘗試寫一個小demo,方便調試Service內部方法或抓取系統日誌來追蹤代碼流程。運行在system_server進程中的Java代碼均可使用Android studio調試,當然必須是自己編譯的image才行。MTK平台手機部分service是可以通過adb shell dumpsys XXX log XX來開啟對應service的log。

接著,從核心API調用入手,一步一步分析源碼,理出一個從應用端到Service端,最後回到應用端的函數調用鏈。這條調用鏈必定很長很長,有非常多的分支,還會出現非常多的類,這個時候就要抓住主線不放,細枝末節可以不管。藉助UML工具了,一般畫兩個圖就夠了,一個是類圖,一個是時序圖。畫圖要精簡,只畫重要的主線分支時序圖和主要的類關係。這個步驟最難的是理出主線分支調用,切記鑽牛角尖偏離目標任務,只需理出一個client--&>service--&>client的框架即可。將時序圖畫出來後,整個框架便構建出來了。(我用starUML工具)

然後,在上面的框架中必定有幾個非常關鍵的函數,把它搞定。搞定方法就是一行一行讀代碼,讀懂每一行並不容易,需要聯繫上下文進行理解。從重要函數中要理清service是如何管理target的,比如AMS是使用Stack和Task來管理Activity的,使用兩個隊列來處理廣播,扮演連接者將client和目標ContentProvider建立起連接等。這個過程也是最花時間的,因為你需要從源碼裡面儘可能地還原作者的設計思想,還原的越徹底,理解的越透徹。一般我是一邊理解一邊用筆記記錄自己的理解。(我用有道雲筆記)

最後,整理出一篇筆記,方便以後回顧。在前面兩步做完,圖有了,分析也有了,稍微整理下便成了一篇文檔。一般情況下是這樣的,今天你理解的差不多了,一個月後你估計只記得大概個輪廓,細節全忘了,兩個月後估計連輪廓都忘了。相信我,這時最管用的就是那兩個圖了,一看就能讓你想起80%,所以我非常喜歡畫類圖和時序圖。

最後的最後,將最開始搜集的那些文章利用零碎時間看一遍,相信我你會發現很多文章分析並不那麼準確。做完這些以後有什麼想更進一步理解的點,只需花極少時間便能搞定,對於寫作能力好的,便可以發文章了。


看什麼書,直接看代碼。

先下載AOSP的代碼樹,完成編譯,最好搞一個nexus,刷到真機測試。

從離你最近的層面看起,把做APP時常用的幾個API搞清楚如何實現。

在一步一步搞清楚的時候,你會遇到進程啟動問題,許可權問題,進程通訊問題,一個API可能涉及AMS、PMS,不要妄圖一下吃透。涉及多少啃多少。不懂的時候可以看書查資料。

當你知道APK安裝是什麼流程,進程啟動什麼流程,嘗到一點兒甜頭,再去找個模塊系統研究。

這時候再了解結構性的東西更有幫助。


謝邀,這只是我個人現在可以想到的一點總結,大家可以多交流一下。

1、首先還是經常說到的計算機的基礎知識,要對基本的硬體,內存的類型有一個大概的了解。有一本書《Linux C一站式編程》,裡面有操作系統標準的Posix介面和IO多路復用及文件描述符等介紹,Android的Lib層都是基於這些操作系統介面實現的,如果看不懂可以多看幾遍,閱讀總是有收穫的。另外還有一半《深入理解計算機體系》也建議閱讀,這本書有點厚。

2、Framework層可以簡單些直接在Android Studio中調試,包括ViewGroup和View對事件的處理,可以查看堆棧信息。另外從ActivityThread的main函數入手,查看Activity是怎麼創建的,生命周期如何回調,View RootImpl是如何創建管理的,都可以從ActivityThread入手。

3、最主要的一點是平時在開發中遇到問題,多閱讀源碼,理解為什麼會這樣,利用源碼解決問題。而不是直接網上找到答案(當然能夠理解到問題所在也不錯)。個人開發過Metro和iOS,Android最大的優勢就是開源,能夠根本的理解到原理。

先寫這麼多了,Pad上打的字,有點累。另外我有幾篇文章,感興趣可以看下,歡迎討論。

Penner - 簡書


謝邀

看了一下這個問題,對於題主說的一些問題有些不同的看法.

看書大家喜歡一次性看完,這個包括我自己都是有這樣的習慣,但是對於Android Framework來說,整個Framework體系的龐大真的不建議所有模塊都想要全部吃掉.在Framework這邊做定製化開發一年多,感覺自己也就對於WM, AM, View, Activity相關的部分理解的比較深入.感覺還是從工作涉及的部分出發比較好.如果沒有特別的側重,可以先從Activity, View, Window整個創建機制和邏輯結構入手,對於APP開發也會提升很多.

關於應該看什麼參考方面,我自己是看老羅CSDN的Android之旅,深入理解Android.雖然這些內容基於的Android版本還是比較老,有些在Android新版本實現轉移了位置甚至整體改變了思路,但是Android這麼長時間整個的框架基本沒有太多的變化.對照現有的代碼,如果有條件的話有一台可以運行AOSP的設備自己做實驗,相信對於Android Framework的學習可以增速很多.

看題主是從應用往Framework過度的,可以自己指定一些計劃來學習,比如:

Activity的生命周期是怎麼實現的, (Activity, AMS, ActivityThread相關)

系統是如何添加一個頂級View或者Window的(WMS, Window, ViewRootImpl相關)

Activity,app是如何進行切換的,後台Activity如何恢復到前台(AMS, ActivityStack, ActivityStackSupervisor相關)

RecentTask是怎麼管理的(AMS, ASSupervisor)

........

怎麼看Android代碼方面,如果僅僅只是期望能看代碼,而且電腦是在Windows環境,SourceInsight確實是一個不錯的選擇,網上相關的配置也比較多,不做贅述.也有一個在線的平台AndroidXRef可以看代碼,支持關鍵字跳轉,在線看看也挺方便.

不過如果想要自己能夠編譯一套Android代碼,同時真機調試.最好的選擇是在Linux環境下進行,同時去https://source.android.com/source/requirements.html 按照教程下載編譯一套代碼(整個過程時間可能非常長,一般代碼有大幾十GB).IDE環境方面,我自己是用Intellij來看的,因為官方支持生成idea的module(mmm development/tools/idegen),導入到intellij也比較方便.而intellij看方法的Hiearchy調用,打斷點調試都非常爽.


首先可以找一些你說的情景分析的其他入門得書來看,等你發現套路和覺得看書還不去老子看代碼的時候你就知道該怎麼學了。

建議,先看電源管理,代碼邏輯相對簡單,明白套路了再看別的。

我覺得你看到一半肯定會去看binder的,蛤蛤。


找個做手機的公司,面framework層,面上了就行。

我從做第三方app轉去做系統app,看framework的源碼時間絕對比你多,但我仍然覺得不入其門。

原因是直接做這方面的工作很多時候是解bug,是會帶有目的性的去讀代碼和調試代碼。而我只是平時看看,就算是調試跟進代碼里了也只是過一過,真有問題還得交給相關同事解決。


其實,我覺得學習framework層的姿勢應該是醬紫的(為啥是姿勢,因為我已經從framework轉應用層好幾年了,現在framework層的知識估計也生疏了許多,尤其是現在android迭代了這麼多版本之後,感覺知識有點脫節。但不管怎麼說,姿勢總是不變滴嘛,呵呵)

1) 工作模塊。framework其實已經不是由許多APP組成了,更應該說的是模塊。比如電量管理模塊(PowerManagerService)、存儲卡(SDCard)模塊、窗口管理模塊(WindowManagerService)、響鬧服務模塊(AlarmManagerService),還有音視頻服務等等,把這些模塊的工作原理、代碼(Java,JNI)等邏輯一個一個吃透了。

2) 調試手段。如果framework層有bug,那麼如何定位問題,編譯新的framework層代碼,已經如何部署到機器上。

a.定位問題:framework層目前可能沒法調試,所以,需要學會抓各個級別的日誌,然後掌握分析問題的技巧。這個沒法具體說,只能自己碰到總結才會。碰到什麼樣的問題,那麼需要搜索什麼樣的關鍵字。

b.編譯模塊:我們只需編譯自己的模塊就好了,不用編譯整個系統,這樣可以大大提升效率。(前提是已經編譯過一遍)這裡提一句,哪些模塊代碼在哪些目錄,你懂了嗎?

c.部署設備上:已經編譯出來的模塊,需要將該模塊導入到手機指定的系統目錄,然後重啟dalvik或art。然後再運行查看。

3)開發利器。SourceInsight目前是查看/學習android源碼很好的工具。

Beyond compare,可以用來對比代碼,也是很好用。尤其是找不到問題時,何不將自己工程的代碼和新版本的代碼做對比,也許Google已經修復這個問題了。

4) 原則。為啥說這個?好像沒啥關係。其實這個關係到你的系統做得好不好。我們盡量不要去修改底層代碼,而是推動其他上層app做優化。給出優化性的意見。盲目地修改底層代碼,可能會帶來很重要的問題。切記。

最後再補一句,書上的東西都是騙人的。哈哈,反正我買的幾本書,都沒派上用場。


找對信息源頭。框架組有自己的mailing list,組員有Google plus賬號。他們會經常分享框架的設計和演進。二十手信息只會增加信息噪音。英語不行就補英語,不要在因為語言在信息質量上吃大虧。


以前代碼看得少的時候,覺得這些都好難啃。

現在看多也就習慣了,然後發現自己懂得更少了。

積累的不夠,看深層次的東西才會覺得晦澀難懂。先學會熟練使用,再去理解,最後才容易更好的摸清楚原理。


第一件要做的是就是:

請在IDE上關聯上源碼。

經常幫助周邊同事解決問題,但是令人懊惱的是,每每想往下看源碼的時候,看的都是class文件反編譯出來的代碼,嚴重影響理解。

其他不多說,Linux,操作系統等等


每次看到 關於Android系統源碼分析就很有感慨,做Android系統級開發近兩年了,算起剛剛進去入門級, 當初也是很迷茫。

我們要明確自己研究Android的目的,短時間看好像真的沒什麼用,如果長期研究,慢慢就會凸顯其價值,從事手機研發,很多問題包括死機功耗性能等都是從android系統級去分析。最初看android確實上手比較難。如果沒有清晰的目標,沒有濃厚的興趣,沒有正確的方法確實難以堅持。

談下自己的學習經歷。

1 在學校是ee專業,課程最喜歡的是微機原理操作系統, 每次上機練習都很積極寫代碼。除了當時就喜歡學linux,自學過linux上的c語言編程,寫過一些代碼,不過現在看來都是玩具代碼。

這個階段是打好基礎的時候,非常重要。 同步非同步阻塞非阻塞,多進程多線程,進程通信,鎖,這都是分析Android必要的基礎知識。

建議 語言層面要會c++,學好操作系統, 熟悉下linux編程,不懂的api查 linux man page.

2 第二個基礎就是,懂java語言,寫過app, 基本的Android會用了,應用層常用類會用。

這個我實習做過app, 自己畢業設計也是寫app演示一個演算法。

3 之後就分析起了源碼。最初是毫無頭緒的,看起來暈暈沉沉的,沒有思路。走過彎路浪費了時間。

然後我去網上搜索各種博客,有很多優秀的文章可以參考,不過看是沒有用的,搞技術一定要親自動手, 看是沒有用的。 所以我從來不去會去細看別人的博客,都是做參考。 因為你花了時間去看那也沒有用,因為你什麼都學不到。

之後我的做法是 根據需要自己分析源碼,遇到不懂的查閱別人的東西,分析過程中記錄文檔畫圖, 都要自己做一遍。這個過程你是有參與感的,而不是做無聊的看客,這樣你會有興趣持續下去,如果只是看我五分鐘都看不了。

所以我現在看源碼一定要打開幾樣東西。

markdown,visio,word,staruml,截圖軟體,source insight, Androidxref網頁, 最終總結輸出到word文檔. 分析過程要站在設計者的角度,多問幾個 為什麼?這樣才能有收穫。比方說Android用binder進程通信,為什麼不用linux原有的機制,很多博客都沒有給出好的回答。

那除了分析學習以外,最好能自己動手寫些代碼實踐下, 比如學過binder機制,可以自己寫兩個native服務進程相互調用,我們團隊原來就遇到過非同步回調不通的問題。學習hal後可以自己封裝個hal模塊.

底層技術就要深挖,越挖知識越多。能學收穫越多,我們能做的也越多。

初期分析源碼,我覺得應該從自己熟悉的部分開始挖掘,比如做app的朋友可以從handler,listview這些常用組件分析起,理解透了,對於提升app代碼質量有幫助的。 熟悉linux編程的朋友可以看native層事件循環looper,以及簡單的守護進程比如healthd,vold.

4 分析複雜一點的源碼,需要一些基礎知識,不能上來就擼代碼。比如說看netd,得知道iptable,nat是啥吧, 看activitymanagerservice,得看官方文檔解釋棧管理機制吧,看surfaceflinger得了解graphic,官方文檔有解釋Android graphic基本原理。

5 即使看了不少源碼,寫了很多文檔,甚至也寫過一些demo小程序,貌似還是會迷茫,這些東西有什麼用呢?

有用,晶元公司和手機需要。

像華為聯發科對底層改動是很多的,有大量人員來維護和開發。

另外,可以從系統層 發起 關於安全,性能,功耗方向的項目。


2011年的時候我帶團隊做Android 2.2-2.3雙卡雙待功能,碰了無數的坑,解決了很多莫名其妙的bug,因此對Android源碼的學習和研究還是有點認識的,特別是telephony,mms,settings,contacts等模塊。

首先,看書基本幫助不大,只能讓你有個印象,混個臉熟。

其次,研究源碼不要貪多,先專註某個模塊或系統App,集中精力弄清楚,如果發現代碼看不懂,趕快去補習設計模式,JVM,多線程方面的知識。需要畫比較詳細的UML類圖和序列圖,對讀懂源碼很有幫助,別嫌麻煩,弄清楚幾百個類和介面的關係已經超過大腦的處理能力。

最後,改系統bug,這個是學習Framework的一個重要目的。這個活需要的是耐心,很多時候幾天也改不了一個bug,需要各種打Log和調試方法。

現在Android系統已經很完善和龐大了,做Framework研發的工作熟悉了後其實比App要簡單,主要工作應該是跟著安卓升級自有的代碼,改Bug,偶爾增加點新功能,增加或適配一些新的硬體模塊, 改改UI等的


看了很多大神答的都全面,挺好的,知乎是個開放平台,像它所說,和世界分享你的經驗,每個人學習方式不一樣,我記得一個同事曾說過,最早寫jni,是從c++開發時的一個業務需求,須要調用調到java層,才了解的jni, android framework是一條漫長的路,做過很多rom相關工程師不敢說完全熟悉,維護的是工作中接觸的一些模塊,個人認為,從你工作中接觸的模塊去學習framework相關,可能更有求知慾望一些。做筆記,畫圖理解關鍵過程是非常有必要的。我分析了一些多媒體相關的總結,拙作,供參考,希望樓主找到自己熱愛的某一領域的framework,然後鋪開,找到合適自己的方式,:

  • Android Multimedia框架總結(一)MediaPlayer介紹之狀態圖及生命周期
  • Android Multimedia框架總結(二)MediaPlayer框架及播放網路視頻案例
  • Android Multimedia框架總結(三)MediaPlayer中創建到setDataSource過程
  • Android Multimedia框架總結(四)MediaPlayer中從Java層到C++層類關係及prepare及之後其他過程
  • Android Multimedia框架總結(五)多媒體基礎概念
  • Android Multimedia框架總結(六)C++中MediaPlayer的C/S架構
  • Android Multimedia框架總結(七)C++中MediaPlayer的C/S架構補充及MediaService介紹
  • Android Multimedia框架總結(八)Stagefright框架之AwesomePlayer及數據解析器
  • Android Multimedia框架總結(九)Stagefright框架之數據處理及到OMXCodec過程
  • Android Multimedia框架總結(十)Stagefright框架之音視頻輸出過程


在知乎上看各種神題神答案,至今未回一帖,看到這裡我感覺與我相關,所以小小的爪機回復哈。

framework如果不是做定製這部分工作的話很少有安卓工程師會去深入關注它(至少大部分),原因是它裡面包含的代碼量太過龐大,並且邏輯嵌套很深,一般系統工程師需要的都是去解bug,目的性很強,用哪看哪!

所以我的想法跟上面幾位大神的想法一樣,找到自己專精的模塊,一路深挖下去,jni,native,甚至可以仔細去研究驅動的代碼,上面有說lightservice就很好!當然作為系統需要理解安卓的通信機制,生命周期等等有用的沒用的。

至於應用層到framework,以我的路數就是binder,handler,pms,systemserver,ams這麼走下來的


謝邀,作為一名普通程序員,我也勉力強答一記。你的這種感覺我到現在也有,就是在面對繁冗複雜的代碼塊時,經常會有種無從下手的困惑。

我認為這是有幾方面原因造成的:

1.基本功不紮實。JAVA語言特性是否都吃透了,操作系統、虛擬機機制是否已經有了清楚的認識。

2.如果上面的答案是「是」的話,你應該看下Android的特性是否有足夠理解了。個人淺見如果對進程間通信有清楚認識,閱讀框架代碼就不應該再有能力上的瓶頸。

3.最後,我認為純粹閱讀源碼的效果,遠不如拿來使用或者給人講解的進步大。前者很好理解,如果你的工作性質就是給框架層改bug或者需要通過框架層機制改造你的代碼,比如前段時間很火的插件化技術,那麼你自然就會對這部分代碼很快上手。我解釋下後者的意思,你可以摘出一個小環節,比如說ams,嘗試給周圍的沒有接觸過的同事講清楚,那麼你在準備材料的過程中充分學習了這個概念。

分享下我讀陌生代碼的一個習慣。腦圖是一種很方便的記憶工具,因為經常會讀著讀著就忘了前頭的方法名或是成員變數名,用腦圖記下來,把彼此關係和調用注意事項記下來,之後再整理和學習的時候也非常方便。


1、有計劃的研究。按照一定的主線,各個模塊逐一擊破;

2、循循漸進的研究。深入android源碼是需要一定的基礎的,在研究各個模塊源碼的過程中,一定會有很多理解不透的地方,若是自學的話,則可以先放著,可以把焦點放在模塊是如何設計的等宏觀問題上。

3、做好筆記。筆記,類圖,時序圖不用說了,再畫一個思維導圖。可以換一個整體的思維導圖,然後不斷補完善。下面就是本人的android思維導圖。

ps:

【主線問題】

有很多關於android系統的書籍,沒有一定基礎的話,可能沒有一本書是適合的,本人在啃這些書的時候就深有體會。

1、系統啟動:

zygote--&>system_server--&>各種服務

native層服務啟動

2、Launcher啟動

3、app的安裝:不論哪一種方式,主要是PMS組織apk各種文件的方式

4、app的啟動:主要就是app調用ams向zygote發出fork新進程的請求,然後zygote啟動ActivityThread主線程,進而執行到相應組件的生命周期。

5、activity的啟動:單個activity的啟動與app啟動是有差異的,不會向zygote發送fork請求。其他都大體一致。

6、view的顯示

7、輸入系統、藍牙、wifi、telephony等等外設模塊。

8、虛擬機

等等。


還在找個做板卡和系統的公司實戰,實踐出真知! 


推薦閱讀:

想買一本安卓的教程書,什麼樣的比較好?
各位 Android 開發者們現在用的是什麼主力手機?
android view的繪製中,View繪製的時間如何和vsync屏幕刷新頻率保持同步的?
android開發,你們還在findviewbyid嗎?
Android程序員技術等級標準?

TAG:Android開發 | Android |