首頁 > 軟體

Android中關於Binder常見面試問題小結

2022-06-29 22:00:43

1.簡單介紹下binder

binder是一種程序間通訊的機制

程序間通訊需要了解使用者空間核心空間

每個程序擁有自己的獨立虛擬機器器,系統為他們分配的地址空間都是互相隔離的。 如兩個程序需要進行通訊,則需要使用到核心空間做載體,核心空間是所有程序共用的一塊記憶體區域。 而使用者空間切到核心空間需要使用到系統api ioctl進行通訊。核心獲取使用者的資料需要使用copy_from_user,核心將資料傳送給其他程序需要使用copy_to_user,這兩個方法是有效能開銷的,對於socket就是使用的這種模式,為了減少這部分的開銷,核心提供了binderbinder只需要一次拷貝就可以實現程序通訊.

主要是使用mmap的原理:

核心空間使用者空間都開闢一塊虛擬記憶體區域同時指向一塊實體地址,這樣核心需要傳遞資料給使用者空間時,只需要將資料拷貝到對應的虛擬記憶體地址中,使用者可以通過虛擬記憶體對映關係,獲取到核心中的資料,實現了一次拷貝通訊。

binder架構上面使用的是C/S架構:

binder中有三要素:
使用者端,伺服器端和ServiceManager

binder整體過程:

1.註冊服務 2.獲取服務 3.使用服務

2.Binder的定向制導,如何找到目標Binder,喚起程序或者執行緒?

資料結構流程:

1.server註冊過程 
      1.server傳入一個flat_binder_object給核心態。核心根據這個flat_binder_object建立binder_node節點,為每個程序服務,內部有個binder_proc.proc = server程序
      2.serviceManager在核心態建立binder_ref參照這個binder_node,內部有一項desc = 1,2,3..,在使用者態會建立一個服務連結串列{name ="server name",handle = "server handle"}
2.client獲取服務過程
      3.client向sm查詢服務,傳遞name
      4.sm返回handle給驅動程式
      5.驅動程式在sm的binder_ref_desc紅黑樹中根據handle找到binder_ref,再根據binder_ref.node找到binder_node,最後給client建立新的binder_ref指向這個binder_node,他的desc從1開始binder_ref{desc=1,node = binder_node},驅動返回desc給client,即handle總結:sm中的handle順序是根據服務註冊順序顯示,返回給client中的handle是根據服務獲取的順序顯示的
3.client使用handle過程
      6.:驅動裡面根據handle找到找到binder_ref,根據binder_ref找到binder_node,根據binder_node找到程序server

注:

flat_binder_object{
    type:是binder實體還是參照,只有需要註冊的服務可以傳binder實體,其他只能傳handle參照
    flag(聯合體)
    binder(實體:處理常式)/handle(參照:服務的參照):
    cookie
}

資料傳輸過程(程序切換):

資料如何複製:

3.Binder中的紅黑樹,為什麼會有兩棵binder_ref紅黑樹

  • refs_by_desc主要是通過desc來查詢對應的binder_ref
  • refs_by_node主要是通過node來查詢對應的binder_ref

查詢方式不一樣

4.Binder一次拷貝原理

傳統的資料拷貝方式如socket

使用者空間---->核心空間:`copy_from_user `
核心空間---->使用者空間:`copy_to_user`

而binder使用mmap機制

在核心空間和使用者空間中間使用實體地址開闢了一個對映關係
核心空間呼叫copy_from_user會直接將資料拷貝到核心空間並反饋到對映後的實體地址上,
由於使用者空間和實體地址也有個對映關係,使用者空間可以直接通過對映的虛擬地址指標存取到寫入實體地址的資料。
這就是binder一次拷貝的原理

5.Binder傳輸資料的大小限制?

對於核心可以傳輸的是4M,但是應用層限制在1M-8K範圍內,這就是在程序間傳輸過大的資料會導致崩潰的原因

6.系統服務與bindService等啟動的服務的區別

系統服務需要將服務註冊到ServiceManager,使用的時候需要通過服務名稱去ServiceManger中獲取服務的參照,

bindService等啟動的服務是將服務註冊到AMS中的ServiceMap中,所有的服務的生命週期都由AMS控制。啟動服務的程序如果需要使用IPC通訊,都是和獲取AMS的代理類進行通訊,AMS也是在SystemServer啟動的時候一個註冊到ServiceManager的系統服務。

7.Binder多執行緒

binder執行緒池預設提供了15個執行緒進行處理程序間並行事件,如果伺服器端執行緒不夠用,則驅動會發出一個訊號,應用層收到這個訊號呼叫Register_Thread,這樣驅動層就可以使用這個新建出來的子執行緒進行資料的處理

8.Android APP程序天生支援Binder通訊的原理是什麼?

Android APP程序都是由Zygote程序孵化出來的。

常見場景

點選桌面icon啟動APP,或者startActivity啟動一個新程序裡面的Activity,最終都會由AMS去呼叫Process.start()方法去向Zygote程序傳送請求,讓Zygotefork一個新程序,Zygote收到請求後會呼叫Zygote.forkAndSpecialize()fork出新程序,之後會通過RuntimeInit.nativeZygoteInit來初始化Andriod APP執行需要的一些環境,而binder執行緒就是在這個時候新建啟動的

virtual void onZygoteInit()
{
    sp proc = ProcessState::self();
    //啟動新binder執行緒loop
    proc->startThreadPool();
}

9.同一個執行緒的請求必定是順序執行,即使是非同步請求(oneway)

一般而言,Client同步阻塞請求Service,直到Service提供完服務後才返回,不過,也有特殊的,比如請求用ONE_WAY方式,這種場景一般主要是用來通知,至於通知被誰消費,是否被消費壓根不會關心。 拿ContentService服務為例子,它是一個全域性的通知中心,負責轉發通知,而且,一般是群發,由於在轉發的時候,ContentService被看做Client,如果這個時候採用普通的同步阻塞勢必會造成通知的延時傳送送,所以這裡的Client採用了oneway,非同步。

到此這篇關於Android中關於Binder常見面試問題小結的文章就介紹到這了,更多相關Android Binder面試內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com