安卓framework開發的初理解

概述
其實咱們寫的App並非一個完整的程序。咱們寫的只是一個套件組,就是一堆Activity,Service等等的組件。這個套件組給Framework框架組合在一塊兒纔是一個完整的程序。在這裏先說一個概念,也就是EIT模型。E是Engine發動機,I是Interface接口,T是tire輪胎。也就是發動機經過接口接上輪胎,而後車子才能跑。而後框架提供的就是E&I,通常框架都是提供發動機和接口,讓咱們來作輪胎,而後裝上就能夠跑起來了。(這裏的I也能夠理解爲抽象函數,由於抽象函數就至關於接口嘛)抽象類也就是把發動機和接口,放在一個類裏。像Activity,提供了一個接口函數(卡隼函數)onCreate(),咱們寫myActivity,就要重寫onCreate(),Activity這個抽象類就是發動機,onCreate()就是接口,myActivity就是輪胎。當框架要Activity運行的時候調onCreate()方法,就帶動了myActivity的運行。咱們寫在onCreate()中的代碼就獲得了執行。linux

Android框架這樣作的好處就是緊緊掌握控制權,要求開發者必須在我給你的接口中裝填代碼,我框架內容變幻無窮你都不用管,你老老實實在我給你的接口填代碼就好了,整個生命週期都由我框架來掌控。試想,若是不經過這種模式,不是給App開發者提供接口,而是直接的函數調用,那框架就要受制於App開發者,這個函數用的人越多,函數改動的成本就越高。框架就被迫不能改變,慢慢也就死了。而經過EIT模型,提供給開發者的只是一個接口,框架對App開發者就是透明的,你只須要在接口中作事就好了,這樣就更規範和靈活。關於何時new Activity的對象是由Framework框架來控制的。Manifest文件裏把Activity註冊上,是由於Framework框架要new Activity的時候知道去哪找這個子類。並且這個對象有什麼初始值,好比響應什麼樣的intent。這樣App的啓動也就好理解了,點擊桌面圖標,由FrameWork框架捕獲這個事件,去找這個圖標對應的App的Manifest裏面找到要啓動的第一個Activity,就是那個在Manifest裏註明是main和luncher的。而後由Framework框架new出這個myActivity對象。天然也就new出了基類Activity對象,而後Framework框架調用Activity的onCreate(),實際對象是myActivity,執行的也就是myActivity的onCreate()。這時候App就啓動了。多線程

因而可知,任何控制類程序都有一個入口,安卓應用程序一樣也是。 
Android framework包含三個小夥伴:服務端、客戶端、linux驅動。框架

服務端
服務端主要包含兩個很重要的類:WindowManagerService(WMS)和ActivityManagerService(AMS)。(兩個大佬管理者服務)異步

客戶端
客戶端包含如下類:函數

ActivityThread:是安卓應用程序的主線程類,也就是UI線程或者稱爲主線程,全部的處理用戶消息,以及繪製頁面的工做都在該線程中完成。oop

Activity: ActivityThread會根據用戶的操做選擇讓哪一個Activity對象上它的船。線程

PhoneWindow:富二代,繼承於牛氣的Window類,本身屋裏住着一個DecorView對象,像它老爸喜歡制定規則提供了一些通用窗口操做API。對象

Window:富一代,長得比較抽象,喜歡制定規則提供了一些通用的窗口操做API。它不喜歡被人管。因此呢,注意:WindowManagerService管理的窗口不是Window類,實際上是View和ViewGroup。繼承

DecorView:很能幹的傢伙,家產來自FrameLayout,比較注重外在喜歡打扮,DecorView是對FrameLayout進行了一些修飾,從名字就能夠看出來。接口

ViewRoot:小管家。繼承於Handler,主要做用是把WMS的IPC調用轉換爲本地的一個異步調用。

W類:ViewRoot小助手,繼承於binder,是ViewRoot內部類。主要幫助ViewRoot實現把WMS的IPC調用轉換爲本地的一個異步調用。

WindowManager:客戶端若是想建立一個窗口得先告訴WindowManager一聲,而後它再和WindowManagerService交流一下看看能不能建立,客戶端不能直接和WMS交互。

Linux驅動
Linux驅動和Framework相關的主要是兩個部分:畫家SurfaceFlingger和快遞員Binder。

每個窗口都對應一個畫Surface,SF主要是把各個Surface顯示到同一屏幕上。Binder是提供跨進程的消息傳遞。

從apk程序的運行過程去看看上面各個組件在啥時候幹啥活的

ActivityThread從main()函數中就開始動起來,而後調用prepareMainLooper()爲UI線程建立一個消息快遞通道即MessageQueue。

接着建立ActivityThread對象,建立過程會建立一個消息裝卸工Handler對象和一個快遞員Binder對象,其中Binder負責接收遠程Ams的IPC調用,接收到調用後讓Handler把消息裝到消息快遞隊列,UI線程很忙的都是異步的從消息快遞隊列中取出消息並執行相應操做,好比 start、stop、pause。

而後UI線程讓隊列調用Looper.loop()方法進入消息循環體,進入後就會不斷地從消息隊列中讀取並處理消息。

當ActivityThread接收到Ams發送start某個Activity的快遞後就會建立指定的Activity對象。Activity會先按窗戶再去按玻璃和貼窗花,因此先建立PhoneWindow->DecorView->建立相應的View或ViewGroup。建立完成後就可讓你們欣賞了,調用WindowManager把界面顯示到屏幕上,而後建立ViewRoot,而後調用Wms提供的遠程接口添加一個窗口並顯示到屏幕上。

接下來就是用戶的操做,事件線程不斷的把消息快遞發到事件隊列中去,而後事件分發線程祕書逐個取出消息,而後調用Wms中的相應函數處理該消息。

不少線程是否是很暈?

安卓程序中都有哪些線程?

客戶端小夥伴至少包含三個線程小弟,Activity啓動後會建立一個ViewRoot.W對象,同時ActivityThread會建立一個ApplicationThread對象,這兩個對象繼承消息總管Binder,每一個Binder對應一個線程,負責接收Linux Binder驅動發送的IPC調用。還有一個是UI線程唄。

自定義的線程和UI線程有什麼區別? UI線程是從ActivityThread運行的,在該類的main()方法中已經使用了Looper.prepareMainLooper()爲該線程添加了Looper對象,已經爲該線程建立了消息隊列,是自帶祕書光環的。所以,咱們才能夠在Activity中去定義Handler對象,由於建立Handler對象時其線程必須已經建立了消息隊列,裝卸工得配運輸帶要否則無法幹活。而普通的Thread則沒有默認建立消息隊列,因此不能直接在Thread中直接定義Handler,這個就是咱們不懂程序運行原理致使的困惑  

相關文章
相關標籤/搜索