360資深Android開發帶你入門Framework

今天,跟你們聊聊,Framework開發的那些事。

系統應用開發,如今來講,已經開始脫離系統,單獨拿出來開發,系統定製接口,已提供給應用調用,用來加強功能。java

原生的桌面,撥號,設置,已經無法作出差別化優點,所以都費盡心機,來進行應用深度開發。linux

對於以前維護系統應用模塊的人來說,修修補補,真的沒有什麼成長。天天的工做來講,沒有很深的技術壁壘,很容易被別人攻陷。算法

好比設置,好比聯繫人,在小的改動,修改故障的時候,沒有很是高的要求,作過應用開發的,均可以過來參合一腳,改改問題。而讓一個應用開發得去修改系統接口,估計改的心累,而且猶豫不決。windows

技術壁壘,也即是本身的競爭優點。只有頑強的技術能力,並鍥而不捨的學習,擴充本身的深度,廣度,那麼你的位置則牢不可破,不會輕易被替代。網絡

Framework的核心技術

這節,小編從自身的角度,講講系統應用開發,該如何向Framework進軍,進行學習,掌握更加核心的技術。數據結構

這裏有人會說,我作應用風生水起,也遊刃有餘,不比大家作系統Framework的差,何須把系統應用開發的貶的一文不值。這裏要說一下,文中沒有這個意思,你的應用作的有聲有色,賺的盆滿鉢滿,這裏確定有其因素。好比它的性能,它的界面絢麗,百變主題。或者它有智能識別,等等。這些都叫作差別化產品,有其亮點,特點,才能殺出重圍。架構

而系統應用開發,我這裏偏向於手機整機開發中的OEM廠商,主要作出系統,可以保證功能正常,不會花費大量人力精力去作應用深度開發,系統重構的。這裏主要會以追求速度,同時知足客戶的硬件要求,好比多個霍爾器件,多個溫度傳感器,多個皮套功能,等等,但不多去大量改動應用架構,以避免影響最終量產。框架

以上,就是特指的這個應用開發人員。隨後,我來說講,Framework須要掌握哪些知識呢?數據結構和算法

操做系統

熟悉個人人都知道,我特喜歡把這個放在第一位,緣由很簡單,它確實支撐了我隨後的全部知識根基,讓我可以從容不迫的,將一個個系統拆解出來。編輯器

咱們就拿安卓來說,啓動過程

Android 啓動過程框架

跟linux一模一樣,因此很容易遷移過來,同時,差別化的init進程,完成初始任務,建立安卓世界的孵化器,既然這裏要進入安卓世界,而安卓世界的基礎語言是java,那麼就須要一個Java虛擬機,因而孵化器就要構造一個虛擬機,用來解析執行Java編譯出來的字節流。而孵化器自己是由c cpp語言實現,因而Java虛擬機就是由c cpp語言寫出來的,linux操做系統也是c(還有一些彙編)寫出來的,因而Java虛擬機運行的Java語言,就須要跟c cpp打交道,因而就有了JNI。

孵化器作了幾件事情:

1.完成Java虛擬機的構造

2.完成JNI對接Java與c的橋樑

3.加載公共的共享庫

4.等待別人給它發消息,建立新進程

在這期間,孵化器要作一件事情,即是建立system_server ,這個進程要作什麼呢?咱們建立了一個能夠運行Java的虛擬機,這時咱們就要提供一堆系統接口,用來協助應用開發,好比請求網絡啦,好比建立界面啦,好比定位啦,獲取存儲卡啦,等等支持,方便用戶開發功能。一個平臺的好壞,每每取決於它的功能是否強大,是否有豐富的技術文檔,以及開發調試工具。

因此就有了一堆線程,好比AMS,WMS,PMS,BT,WIFI,這些均可以在/proc/{ system_server_pid}/ tast找到記錄。

有了這些線程,那麼咱們就能夠輕鬆的去實現不少功能啦。這時咱們就要配套的開發工具,好比AS編輯器,能夠編輯,編譯出來APK,安裝到手機運行。

關於操做系統,須要掌握的知識點爲:

1.進程,線程概念

2.互斥,死鎖機制與原理,如何避免死鎖

3.內存管理機制,虛擬內存

4.靜態庫與動態庫的區別

5.進程之間的內存屏障,如何通訊(IPC)

6.binder的通訊優點

這裏先想到這些,注意不是要完成懂全部機制,要的是總體理解便可。以下問題,請思考下,看是否可以答上來。

若是我寫了一個應用,名字叫作,com.codegg.home 在主activity裏面,加載一個佈局,layout_main. xml,佈局裏面寫入了一個TextView,那麼我想調試這個TextView,要在com.codegg.home這個進程下斷點,仍是在system_server進程下斷點呢?若是是想調試ActivityThread. java的話?應該在哪一個進程下斷點呢?

以上答案,都是com.codegg.home下斷點,緣由是這兩個當前的運行進程,都是在com.codegg.home裏,因此要調試的話,要在com.codegg.home進程下斷點。

那麼咱們再來思考下,我如今要去追應用的啓動過程,start Activity的流程,要在哪一個地方下斷點呢?

咱們知道這個流程,最終核心的都在Activity manager server裏面,而它是在system server進程裏面,以一個線程的狀態存在,因而咱們要調試,就要在system server上面下斷點了。

搞清楚了system server後,以咱們熟悉的AMS WMS PMS 舉例。這些服務線程,完成應用的請求任務,將結果返回給應用。好比查看當前運行的全部Activity,就是應用發起請求,從操做系統那裏,先找到server manager,這個手裏拿到一堆服務的句柄,也能夠說令牌,你只能經過這個找到它。

當server manager一看你有權限,就幫你把對應的AMS的句柄給你,這個句柄操做系統也認識,對應到system server的AMS引用上,也就是你經過這個句柄,調用它的方法,操做系統就會將你的請求,傳遞到system server中去,同時操做系統知道這個句柄是AMS的第20號(這個20號表明查詢當前運行的全部Activity的方法),而後就喚醒system server,同時從binder線程池,這個線程跟AMS同樣,是個線程,從線程池拿出一個,調用AMS的20號方法。

調用完成後,從操做系統層面,把數據交給調用的應用,實現數據傳輸。這裏面定義的傳遞數據格式是包裹,也就是序列化數據。

瞭解進程通訊

好了,這塊就說這麼多,主要是說下進程通訊,以及binder這種通訊的簡單邏輯。這裏說下,爲何要通訊。

由於操做系統設計,管理的軟件單元是進程,進程間自己不聯繫,彼此看不見。一個進程想跟另外一個說話,他兩都認識的人是操做系統。由於他們是由操做系統管理的。操做系統經過從硬盤將程序裝載進入內存,同時給每個分配了進程號,因而他們就都在系統裏面有了標記,同時每一個都起了名字,一個叫我就喜歡吃,一個叫我就喜歡喝。喜歡喝的一我的孤單,他不認識喜歡吃的,他就問操做系統,有沒有人喜歡吃的,操做系統一查,說有啊,而後把喜歡吃的的進程號給他,他就能夠找到喜歡吃的了。

而後操做系統給他了一輛車,讓他把想給喜歡吃的的東西,裝在車上寄過去。這個車子是操做系統提供的,這個車子就是通訊方式。好比汽車,飛機,步行。

因而進程間的通訊方式就是,從操做系統找到目標,而後拿到通訊方式,用操做系統給的通訊工具,進行通訊。

數據結構和算法

這塊完成了,咱們再來說一個內容:

文件=文件頭+文件內容

咱們發現,這裏MP3格式,OGG格式,都屬於一個文件的格式聲明,這個咱們能夠用HEX工具打開MP3文件,能夠看到剛開始的位置,這塊屬於描述後面的內容該如何解析,好比文件名字,文件大小,文件格式,系統根據這個描述,嘗試用對應的解碼器解碼,解碼完成後進行播放。

這裏解碼器如何解碼,就是算法。而文件頭,就是描述這個文件的數據結構。

因而,咱們就知道

程序=數據結構+算法

好比我要寫個貪吃蛇,如何描述蛇的狀態,長度,當前軌跡,這些都是須要表徵出來,而後圍繞着這個描述內容,進行操做,這塊就屬於算法。

完成的程序,運行起來,就是進程。因此進程是一個存在於內存的東西,操做系統用一個表格記錄進程數據,好比進程號,父類進程,進程打開的文件句柄,進程當前狀態,進程的上下文(上下文是保存當前CPU的寄存器,保存現場用的,由於寄存器是隻有一份,當一個進程被打斷時候,另個進程運行,那麼以前的就要把它當前的寄存器存下來,防止被別人蓋掉,等到下次本身運行的時候,再恢復回來,保證本身運行正常),程序是存在硬盤或者其餘存儲設備,掉電不會丟失,而進程是內存的,因此掉電就再也不了。

**程序如何加載,系統如何識別的呢?**這就又回到開頭的地方,數據結構加算法,也叫文件頭和文件內容。源碼通過編譯連接,變成一個文件,咱們親切的叫它可執行文件。那麼咱們來講說它。

咱們常見的兩種可執行文件,windows上面稱爲PE格式,linux稱爲ELF,二者都是從COFF格式演化來的,這塊參考《連接器與加載器》,喜歡感興趣,能夠下載閱讀此書。

程序是如何在CPU執行的?

那麼有了格式描述,操做系統就知道如何解析它了,而後把對應的代碼段,數據段,堆棧區域配置好,將代碼裝載進入內存中,而後將下一條執行位置,也就是PC寄存器,指向這個可執行文件配置的text 入口,這個就是程序的入口點,這個咱們去寫的main方法,能夠簡單理解成入口,實際狀況是在這個前面,系統加入了一些代碼,爲運行此程序作準備,準備OK纔會真正調用到main方法,這段代碼叫建立此進程的環境,好比參數,堆棧初始化。

聊到這裏,咱們從別的緯度,再來看看。

數字電路的與或非邏輯電路,開啓了新世界的大門。咱們用斷點,通電,表示兩個狀態。咱們不能說,好像有電,好像沒電,因此,計算機的世界,定義了二進制,由於是非能夠界定,孰是孰非很差界定。

因而,在咱們的電路板上,規定了0-0.6V,表明了沒電,4.4-5V,表明了有電,中間的數值,表明了器件的錯誤,不穩定性。

因而沒電用0表示,有電用1表示,實際世界就是兩個區間電壓。

CPU在石英晶振的推進下,執行一條條指令。指令是什麼呢?就是一串串數字,每一串表明一個具體含義。

因此,CPU可以執行多少條指令,是考量它是否強大的一個重要參數,另外一個是它執行一天指令的時間,也叫指令週期,越短越好。也就是兩個CPU同時作一個加法,誰用時短誰就強。

CPU拿到一條指令,就會在石英晶振的推進下,將這條指令執行完,而後將PC寄存器加1,讀取下一條指令。

咱們常常遇到的非法指令,就是由於CPU拿到了一個不認識的數據串,致使異常。好比它的指令集裏面,有加法,有減法,你給他說你給我翻個跟頭(非法指令),他罵了一句去你的吧,老子不會(異常報錯)。通常這種狀況是指令不識別,好比你用了新的arm指令,又在舊的arm板子運行這個程序,就會掛掉,提示非法指令。

剛開始的操做系統,嵌入式的操做系統,是沒有作內存保護,就是程序段能夠跳到數據段執行,固然如今加入了內存管理單元,會將數據段內存描述成可讀可寫不可執行,若是PC(程序寄存器)指向了這個地方,去讀取執行的時候,就會報非法訪問。

若是沒有保護,你去讀取數據段的數據,做爲指令執行,出現指令異常就太正常了。

好了,今天就給你們介紹這麼多,有什麼想方法或者建議歡迎留言評論。

以爲文章還不錯喜歡的點個贊給個喜歡鼓勵下唄~

相關文章
相關標籤/搜索