目前,互聯網行業正在朝着移動互聯網方向強勁地發展,而移動互聯網的發展離不開背後的移動平台的支撐; 衆所周知,如今在移動平台市場上,蘋果的iOS、谷歌的Android和微軟的Windows Phone系統已經形成了三足鼎立的形勢,而Android系統的市場占有率是最高的
Android系統之所以能夠在市場上占據着第一的位置,一來是因為它依托着谷歌的品德效應和技術實力,二來是因為它是開放的,任何人都可以得到它的源代碼,并且能夠自由地使用它; 既然Android系統是開放的,作為一個移動平台開發人員來說,當然希望能夠深入地去分析和研究它的源代碼了,然而,Android系統的源代碼非常龐大,我們需要循序漸進地去學習
工欲善其事,必先利其器; 為了全面、深入地理解Android系統的源代碼,在正式進入Android系統源代碼的世界前,我們需要準備實驗環境;此外,還需要了解Android系統的架構知識
硬件環境要求1、編譯環境按照官方的說法,編譯Android 2.3.x及以上版本的系統源碼需要64位的系統運行環境來支持,而編譯2.3.x以下的版本則需要32位的系統運行環境
2、硬盤空間官方建議最好預留100G的磁盤空間來下載源碼,150G的磁盤空間用來編譯源碼,如果使用了ccache(一個高速編譯緩存工具,可以大幅加快gcc的編譯速度),那麼則需要更大的空間來支持
所以盡可能地保證自己的磁盤空間夠大吧,之前就因為磁盤空間預留不夠導緻源碼編譯過程中空間不足,狠狠地把自己坑了一把
3、内存空間如果你是在虛拟機上跑Linux,官方建議至少需要16G的内存空間,我的機器隻有8G的内存空間跑虛拟機,目前跑起來也沒太大問題,就是編譯源碼的過程非常漫長,不知道是否跟内存大小有關
軟件環境要求1、操作系統Android系統的源碼的編譯支持 Linux 跟 Mac OS 兩種操作系統; 一般情況下,Android系統源碼都是在Linux Ubuntu系統上進行開發與測試的,所以如果你準備使用Linux系統來進行源碼編譯,那一般推薦安裝Ubuntu版本的Linux
下面列出了各Android版本與編譯系統版本的對應關系:
Linux:
Mac OS:
2、JDK 版本要求
不同的Android版本編譯也需要對應的JDK環境,這裡列出了各版本之間的對應關系
環境搭建
開發Android應用程序可以在兩種環境下進行; 一是在Android SDK環境下進行,一般是集成在Eclipse裡面進行開發,二是在Android源代碼工程環境下進行,在這種環境進行開發的好處是可以使用一些在SDK中不公開的接口
但是如果我們要修改Android系統的源代碼,或者為Android系統增加新的功能接口,那麼就隻能在Android源代碼工程環境下進行了; 由于我們的目的是對Android系統源代碼進行分析,因此,我們在開發Android應用程序時,也在Android源代碼環境下進行;這樣,我們就需要搭建一套Android源代碼工程環境了
目前,Android源代碼工程環境隻能在Linux平台上使用,而Linux系統的發行版本比較多,這裡我們推薦Ubuntu系統; Ubuntu系統是免費的,而且非常易于使用,安裝和更新應用程序也非常方便
安裝好Ubuntu系統之後,我們就可以在上面下載、編譯和安裝Android源代碼了
Android系統的源代碼工程默認是不包含Linux内核源代碼的; 如果我們需要修改Android系統的内核或者在裡面增加新的模塊,那麼就要把Android内核源代碼一起下載、編譯和安裝了
Android源代碼工程環境搭建好了之後,我們就可以在裡面開發新的應用程序或者修改系統代碼了; 增加了新的應用程序或者修改了系統的代碼之後,不需要重新編譯整個源代碼工程,隻要單獨編譯有改動的模塊就可以了
對于已經開發好的應用程序或者系統功能; 如果想把當作Demo展示給客戶來體驗時,我們既可以在真機上面運行,也可以在模拟器(Android源代碼工程環境或者Android SDK環境都集成了模拟器)上面運行
當我們手頭上沒有真機,而且我們又不想把整個Android源代碼工程環境或者Android SDK環境帶去展示我們的Demo時,就可以考慮把模拟器這兩個環境中獨立出來了
系統架構Android系統是按層次、分模塊來設計的; 在我們着手對Android系統的源代碼進行分析前,需要對Android系統的架構有一個總體的認識,這樣我們就能夠快速地知道哪些代碼位于哪個層次上的哪個模塊中,節省搜索代碼的時間,把更多的精力投入在源代碼的分析上去
整個系統劃分内核空間和用戶空間兩部分; 内核空間包含了進程管理、内存管理以及設備驅動程序模塊等,其中Android專用驅動Binder、Logger和Ashmem就是在内核空間實現的
用戶空間包含了硬件抽象層(HAL)、外部庫和運行時庫層(External Libraries & Android Runtime)、應用程序框架層(Application Framework)和應用程序層(Applications)四個層次; 我們應該如何去掌握這個層次結構呢?最好的方法就是從學習Android的硬件抽象層作為切入點了
可能大家會覺得比較奇怪,為什麼要把Android系統的硬件抽象層作為學習Android系統架構的切入點呢?
其實是這個層次因為涉及到硬件,看起來這是一個比較複雜和深奧的知識點; 實則不然,Android系統的硬件抽象層在實現和使用上,層次都是非常清晰的,它從上到下涵蓋了Android系統的用戶空間和内核空間
内核空間主要就是涉及到硬件驅動程序,而用戶空間就涉及到了Android系統應用程序層、應用程序框架層和系統運行時庫層的相關知識; 因此,學習Android系統的硬件抽象層,可以使大家快速地認識整個Android系統,從而對Android系統得到一個感性的認識,為後面深入分析Android系統的源代碼打下良好的基礎
學會了編寫基本的Android應用程序并且對Android系統的整體架構有一個大概的了解之後,我們就可以去分析Android系統的源代碼了
在分析Android源代碼的過程中,我們經常進入到應用程序框架層去分析它的源代碼; 而在應用程序框架層中,有一部分代碼是使用C 來實現的,這時候就會經常碰到智能指針,因此,我們把Android系統中的智能指針也作為一個基礎知識點來學習
相信使用過C 語言來做開發的讀者對智能指針不會感到陌生; 用C 來寫代碼最容易出錯的地方就是指針了,一旦使用不當,輕則造成内存洩漏,重則造成系統崩潰,因此,系統為我們提供了智能指針,避免出現上述問題
在Android系統中,提供了三種類型的智能指針,分别是輕量級指針、強指針和弱指針,它們都是基于對象引用計數技術來實現的;
輕量級指針的計數技術比較簡單,隻要對象的引用計數值為0,它就會被釋放
強指針和弱指針的計數技術相對比較複雜; 一個對象可以同時被強指針和弱指針引用,但是這個對象的生命周期一般隻受強指針的控制,即當這個對象的強引用計數為0的時候,這個對象就被釋放了,即使這時候這個對象的弱引用計數不為0
引進強指針和弱指針這種複雜的引用計數技術是為了解決垃圾收集(Garbage Collection)問題而提出的; 考慮這樣的一個場景,系統中有兩個對象A和B,在對象A的内部引用了對象B,而在對象B的内部也引用了對象A
當兩個對象A和B都不再使用時,垃圾收集系統會發現無法回收這兩個對象的所占據的内存的; 因為系統一次隻能收集一個對象,而無論系統決定要收回對象A還是要收回對象B時,都會發現這個對象被其它的對象所引用,因而就都回收不了,這樣就造成了内存洩漏
如果采用強指針和弱指針技術,這個問題就迎刃而解了,即A和B都用弱指針來引用對方
尾述文章基本上就到這裡,文章隻是對 Android 源碼做了一些個人理解的東西,如有地方不對或者有不同理解的可以提出來
有需要獲取更多Android相關資訊的同學 可以 私信發送 “進階” 或 “筆記” 即可 免費獲取
現在發送還可以獲得 更多《Android 學習筆記+源碼解析+面試視頻》
最後我想說:
對于程序員來說,要學習的知識内容、技術有太多太多,要想不被環境淘汰就隻有不斷提升自己,從來都是我們去适應環境,而不是環境來适應我們
當程序員容易,當一個優秀的程序員是需要不斷學習的; 從初級程序員到高級程序員,從初級架構師到資深架構師,或者走向管理,從技術經理到技術總監,每個階段都需要掌握不同的能力。早早确定自己的職業方向,才能在工作和能力提升中甩開同齡人
技術是無止境的,你需要對自己提交的每一行代碼、使用的每一個工具負責,不斷挖掘其底層原理,才能使自己的技術升華到更高的層面
Android 架構師之路還很漫長,與君共勉
PS:有問題歡迎指正,可以在評論區留下你的建議和感受;
歡迎大家點贊評論,覺得内容可以的話,可以轉發分享一下
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!