Android的一些設計思想(201603)

desaco發表於2016-02-24

> 設計思想

Java物件導向設計思想-堆溢位(OutOfMemoryError),棧溢位(StackOverFlowError),封裝、繼承、多型性

Android設計思想-四大元件新建,不用new 關鍵字,而是Framework框架層的IOC控制,Intent, Binder ,程式與執行緒 Manager(AMS WMS)等;


 > Binder全貌
Native 實現:  IBinder,  BBinder, BpBinder, IPCThread, ProcessState, IInterface, etc
Java 實現:  IBinder, Binder, BinderProxy, Stub, Proxy.
Binder Driver: binder_proc, binder_thread, binder_node, etc.

   Binder IPC機制

     Android系統中大量使用了基於C/S模式的通訊方式。諸如簡訊操作,電話操作,視訊音訊捕獲,感測器等都以服務(Service)的形式提供,並由相應的Server負責管理.
     模式的支援,Android採用了一種基於共享記憶體的IPC機制——Binder機制。

  binder 通訊是一種 client-server 的通訊結構, 
    1. 從表面上來看,是 client 通過獲得一個 server 的代理介面,對 server 進行直接呼叫; 
    2. 實際上,代理介面中定義的方法與 server 中定義的方法是一一對應的; 
    3.client 呼叫某個代理介面中的方法時,代理介面的方法會將 client 傳遞的引數打包成為 Parcel 物件; 
    4. 代理介面將該 Parcel 傳送給核心中的 binder driver. 
    5.server 會讀取 binder driver 中的請求資料,如果是傳送給自己的,解包 Parcel 物件,處理並將結果返回; 
    6. 整個的呼叫過程是一個同步過程,在 server 處理的時候, client 會 block 住。
    Binder機制的本質是共享記憶體,共享記憶體區的管理完全由Binder驅動來完成,對應用層的Client和Server來說是完全透明的。
    Client和Server均通過函式ioctl與Binder驅動進行資料互動。ioctl是Linux中用於控制I/O裝置的函式,提供了一種同時向裝置傳送控制引數和資料的手段。

 應用和 service 之間的通訊會涉及到 2 次 binder 通訊。 
   1. 應用向 SM 查詢 service 是否存在,如果存在獲得該 service 的代理 binder ,此為一次 binder 通訊; 
   2. 應用通過代理 binder 呼叫 service 的方法,此為第二次 binder 通訊。

 ProcessState 是以單例模式設計的。每個程式在使用 binder 機制通訊時,均需要維護一個 ProcessState 例項來描述當前程式在 binder 通訊時的 binder 狀態。 
    ProcessState 有如下 2 個主要功能: 
    1. 建立一個 thread, 該執行緒負責與核心中的 binder 模組進行通訊,稱該執行緒為 Pool thread ; 
    2. 為指定的 handle 建立一個 BpBinder 物件,並管理該程式中所有的 BpBinder 物件。 

ProcessState 中有 2 個 Parcel 成員, mIn 和 mOut , Pool thread 會不停的查詢 BD 中是否有資料可讀,如果有將其讀出並儲存到 mIn ,同時不停的檢查 mOut 是否有資料需要向 BD 傳送,如果有,則將其內容寫入到 BD 中,總而言之,從 BD 中讀出的資料儲存到 mIn ,待寫入到 BD 中的資料儲存在了 mOut 中。
ProcessState 中生成的 BpBinder 例項通過呼叫 IPCThreadState 的 transact 函式來向 mOut 中寫入資料,這樣的話這個 binder IPC 過程的 client 端的呼叫請求的傳送過程就明瞭了 。

 瞭解了 native 通訊機制後,再去分析 JAVA 層的 binder 機制,就會很好理解了。它只是對 native  binder 做了一個封裝。

從應用程式的角度看Binder一共有三個方面: 
Native 本地:例如BnABC,這是一個需要被繼承和實現的類。 
Proxy 代理:例如BpABC,這是一個在介面框架中被實現,但是在介面中沒有體現的類。 
客戶端:例如客戶端得到一個介面ABC,在呼叫的時候實際上被呼叫的是BpABC 




Handler訊息機制

與Handle工作的幾個元件Looper、MessageQueue各自的作用:
  1.Handler:它把訊息傳送給Looper管理的MessageQueue,並負責處理Looper分給它的訊息
   2.MessageQueue:採用先進的方式來管理Message
   3.Looper:每個執行緒只有一個Looper,比如UI執行緒中,系統會預設的初始化一個Looper物件,它負責管理MessageQueue,不斷的從MessageQueue中取訊息,並將
                    相對應的訊息分給Handler處理


> 理解AIDL其工作原理

  關於AIDL的介紹在文件:docs/guide/developing/tools/aidl.html
  關於IBinder的介紹在文件:docs/reference/android/os/IBinder.html
  以及Binder:docs/reference/android/os/Binder.html
  在Android上,一個程式無法正常訪問另一個程式的記憶體,而AIDL可以為你實現。
AIDL是一個介面描述檔案,用於實現Android平臺上面的RPC,aapt在編譯的時候會自動根據規則生成用於IPC的介面和物件,而作為使用者只需要:1.在服務端Service實現介面;2. 在客戶端bindService,onServiceConnected時獲取介面物件。這裡的介面都是AIDL中描述的介面,其他的細節則在由AIDL生成的同名原始碼檔案中。

   本質--脫去內衣
其實AIDL的作用就是對Binder的二個方法:Binder.transact()和Binder.onTransact()進行封裝,以供Client端和Server端進行使用。因為實現transact()和onTransact()方法的方式基本上是相同的,所以就可以用模板來生成具體的程式碼。理論上講只需要為Client端生成transact()相關程式碼,為服務端生成onTransact()程式碼即可,但因為工具無法準確的確定某一個應用到底是Client端還是Server端,所以它就生成所有的程式碼,放在一個檔案中。這就是你看到的自動生成的檔案。
還需要注意的一點是Client端的Proxy是組合Binder物件,呼叫其transact()方法;而服務端必須繼承Binder物件,覆寫onTransact()方法。為蝦米呢?因為Client是主動發起IPC函式Call,所以它可以直接呼叫Binder的方法來進行IPC。而Server是被動的,是要接收進來的IPC call,但Service自己無法得知啥時候Call會來,因此必須實現回撥(onTransact())給Binder,以讓Binder在有IPC Call進來的時候告訴Service。
   原理和內幕
AIDL的角色是實現Android平臺上面的RPC(Remote Procedure Call)也即遠端例程呼叫。RPC是IPC中的一種,但是它是以呼叫在本地或者另一個程式,甚至是另一個主機上的方法的機制。RPC的目的就是可以讓程式不用擔心方法具體是在哪個程式裡面或者哪以機器上面,就像正常的本地方法那樣去呼叫即可,RPC機制會處理所有的具體細節。RPC一般用IDL(Interface Definition Language)來描述,實現則要看具體的平臺和語言。可以參考Wikipedia來看RPC 和IDL 的更多資訊。
AIDL提供Android平臺的RPC的支援:開發者僅需要要定義AIDL,做一些相關的適配工作,然後就可以使用這些方法了,不用具體關心介面描述的方法空究竟是在同一個程式中還是在其他的程式中。這些RPC實現的細節由Binder和系統來處理。

    客戶Proxy的transact,和服務Stub的onTransact使用二個標識來識別對方:一個是DESCRIPTOR,這個是標識Binder的Token,也就是說是標識服務端和客戶端;方法的標識就是TRANSACTION_print,是用來標識呼叫的是哪個方法。這個理解起來也不是很難,就好比打電話,先要通過通訊的標識電話號碼找到相應的人,然後跟人說的時候要告訴他是哪件事(哪個方法)。
接下來可以二個方面來進行深入的研究:
  1. bindService是如何獲得Binder物件的(無論是本地時Service的實現,還是遠端時的BinderProxy),或者說是如何查詢到Binder物件。
這是ServiceConnection.onServiceConnected的呼叫棧:
  2. Binder.transact()和Binder.onTransact()的細節,這也是具體Binder IPC機制的細節。


> ServiceManager、ActivityManager、XXXManager是幹什麼的?
  C/S框架及代理 框架IOC

服務程式                          管理的服務
com.android.phone       與通訊功能相關的簡訊、電話服務
mediaserver                    與媒體功能相關的視訊、音訊服務
system_server                其他服務,如地理位置、藍芽、網路連線、程式安裝解除安裝等


- AIDL:熟悉AIDL,理解其工作原理,懂transact和onTransact的區別; 

- Binder:從Java層大概理解Binder的工作原理,懂Parcel物件的使用; 
- 多程式:熟練掌握多程式的執行機制,懂Messenger、Socket等; 
- 事件分發:彈性滑動、滑動衝突等; 
- 玩轉View:View的繪製原理、各種自定義View; 
- 動畫系列:熟悉View動畫和屬性動畫的不同點,懂屬性動畫的工作原理; 
- 懂效能優化、熟悉mat等工具 
- 懂點常見的設計模式

1.瞭解SystemServer的啟動過程 
2. 瞭解主執行緒的訊息迴圈模型 
3. 瞭解AMS和PMS的工作原理 
4. 能夠回答問題”一個應用存在多少個Window?“ 
5. 瞭解四大元件的大概工作流程 。。。。。。

rx 知道麼?圖片三級快取? OOM ? 得說一些思想出來??? Eventbus  volley 之類有熟悉的麼,主要是思想?  常見設計模式,你要列出來有哪些??

EvnetBus的下載地址:https://github.com/greenrobot/EventBus.git


> gravity與layout_gravity的區別

android:gravity:設定的是控制元件自身上面的內容位置
android:layout_gravity:設定控制元件本身相對於父控制元件的顯示位置。


《未完待續》

相關文章