助攻面試:圖解Android Binder機制

2021-03-02 碼個蛋

碼個蛋(codeegg) 第 936 次推文

作者:Hanking
連結:https://juejin.im/post/5e89f717f265da47e6491496


Binder做為Android中核心機制,對於理解Android系統是必不可少的,關於binder的文章也有很多,但是每次看總感覺看的不是很懂,到底什麼才是binder機制?為什麼要使用binder機制?binder機制又是怎樣運行的呢?這些問題只是了解binder機制是不夠的,需要從Android的整體系統出發來分析,在我找了很多資料後,真正的弄懂了binder機制,相信看完這篇文章大家也可以弄懂binder機制。


要理解binder,先要知道IPC,Inter-process communication ,也就是進程中相互通信,Binder是Android提供的一套進程間相互通信框架。用來多進程間發送消息,同步和共享內存。已有的進程間通信方式有一下幾種:

1、Files 文件系統(包括內存映射)

2、Sockets 

3、Pipes 管道 

4、共享內存 

5、Intents, ContentProviders, Messenger 

6、Binder

Android系統中的Binder框架圖如下:

拿Activity舉例從上圖可以看出來:Activity是由ActivityManager來控制的,而ActivityManager其實是通過Binder獲取ActivityManagerService服務來控制Activity的,並且ActivityManager是Android系統FrameWork層的,和應用中的activity不是同一個進程。

重點

1、Binder是Android提供的一套進程間通信框架。

2、系統服務ActivityManagerService,LocationManagerService,等都是在單獨進程中的,使用binder和應用進行通信。



如上圖,Android系統分成三層。最上層是application應用層,第二層是Framework層,第三層是native層。由下圖可知幾點:

1、Android中的應用層和系統服務層不在同一個進程,系統服務在單獨的進程中。

2、Android中不同應用屬於不同的進程中。

Android應用和系統services運行在不同進程中是為了安全,穩定,以及內存管理的原因,但是應用和系統服務需要通信和分享數據。


優點

安全性:每個進程都單獨運行的,可以保證應用層對系統層的隔離。

穩定性:如果某個進程崩潰了不會導致其他進程崩潰。

內存分配:如果某個進程以及不需要了可以從內存中移除,並且回收相應的內存。


client請求service服務,比如說Activity請求Activity ManagerService服務,由於Activity和ActivityManagerService是在兩個不同的進程中的,那麼下圖是一個很直觀的請求過程。


但是注意,一個進程是不能直接直接操作另一個進程的,比如說讀取另一個進程的數據,或者往另一個進程的內存空間寫數據,進程之間的通信要通過內核進程才可以,因此這裡就要使用到進程通信工具Binder了如下圖:



Binder driver通過/dev/binder 

/dev/binder 提供了 open, release release, poll poll, mmap mmap, flush flush, and ioctl 等操作的接口api。這樣進程A和進程B就可以通過內核進程進行通信了。

進程中大部分的通信都是通過ioctl(binderFd, BINDER_WRITE_READ, &bwd)來進行的。bwd 的定義如下:

struct binder_write_read {    signed long write_size;   signed long write_consumed;     unsigned long write_buffer;   signed long read_size;     signed long read_consumed;      unsigned long read_buffer;};


但是上面還有個問題就是client和service要直接和binder driver打交道,但是實際上client和service並不想知道binder相關協議,所以進一步client通過添加proxy代理,service通過添加stub來進一步處理與binder的交互。


這樣的好處是client和service都可以不用直接去和binder打交道。上面的圖好像已經很完善了,但是Android系統更進一步封裝,不讓client知道Binder的存在,Android系統提供了Manager來管理client。如下圖:


這樣client只需要交給manager來管理就好了,根本就不用關心進程通信相關的事,關於manager其實是很熟悉的,比如說activity的就是由ActivityManager來控制的,ActivityManager是通過Binder獲取ActivityManagerService來控制activity的。這樣就不用我們自己來使用Binder來ActivityManagerService通信了。

更進一步,client是如何具體獲取到哪個service的呢?如下圖所示:


在service和binder之間還有一個contextManager,也就是serviceManager,每一個service要先往serviceManager裡面進行註冊,註冊完成之後由serviceManager統一管理。在Android studio中可以通過adb指定列印出當前已經註冊過serviceManager的service。

$ adb shell service list Found 71 services: 0 sip: [android.net.sip.ISipService] 1 phone: [com.android.internal.telephony.ITelephony] … 20  location: [android.location.ILocationManager] … 55  activity: [android.app.IActivityManager]  56  package: [android.content.pm.IPackageManager] …  67  SurfaceFlinger: [android.ui.ISurfaceComposer]  68  media.camera: [android.hardware.ICameraService]  69  media.player: [android.media.IMediaPlayerService] 70  media.audio_flinger: [android.media.IAudioFlinger]

下圖是一次更加完整的client和service的通信流程:


在看Binder框架之前,先來看一下,從client發出請求service的完整的流程。

獲取服務過程:


第一步:client要請求服務,比如說在activity中調用context.getSystemService()方法,這個時候serviceManager就會使用getService(name),然後就會調用到native層中的ServiceManagerNative類中的getService(name)方法。

第二步:ServiceManagerNative會通過Binder發送一條SVG_MGR_GET_SERVICE的指令,然後通過svcmgr_handler()調用do_find_service()方法去svc_list中查找到相關的service。

第三步:查找到相應的服務後就會通過Binder將服務傳給ServiceManagerNative,然後傳給serviceManager,最後client就可以使用了。

注意: 服務實在svclist中保存的,svclist是一個鍊表,因此客戶端調用的服務必須要先註冊到svclist中。

註冊服務過程:


第一步: service通過調用serviceManager中的addService方法,然後調用ServiceManagerNative類中的addservice(name)方法。

第二步: ServiceManagerNative會通過Binder發送一條SVG_MGR_ADD_SERVICE的指令,然後通過svcmgr_handler()調用do_add_service()方法往svc_list中添加相應的service。

重點:所有的服務都要先註冊到svc_list中才能被client調用到。svc_list以linkedlist的形式保存這些服務。


Binder結構設計要了解binder的結構設計,就要了解Android的體系結構,Android是分成application層,framework層native層,以及內核層,Binder設計在每一層上都有不同的抽象。如下圖:


由上圖可知Binder的整體設計總共有四層:

1、Java層AIDL。

2、Framework層, Android.os.Binder 。


framework層中最重要的數據結構是transaction,有一下幾個默認的:

3、Native 層: libBinder.cpp

在native層主要是libBinder


4、內核層內核層的通信都是通過ioctl來進行的,client打開一個ioctl,進入到輪詢隊列,一直阻塞直到時間到或者有消息。


1、代理模式(Proxy Pattern )在Android中client不是直接去和binder打交道,client直接和Manager交互,而manager和managerProxy交互,也就是說client是通過managerProxy去和binder進行交互的。同時service也不是直接和binder交互,而是通過stub去和binder交互。如下圖。


2、Bridge Pattern如下圖,應用層也就是Java層要使用MediaPlayer,就要調用native層中的MediaPlayer.cpp,但是MediaPlay.java不是直接去跟JNI打交道,而是通過與MediaPlayerSevice通信,從而經過Binder返回的。


今天的文章就到這裡了,圖還是挺多的,有沒有覺得好理解多了?

相關文章:

今日問題:

Binder理解得怎麼樣啦?

專屬升級社區:《疫魔無情碼個蛋有愛,招聘社區助大家找到更心怡的工作》 

相關焦點

  • 【android開發】Android binder學習一:主要概念
  • 歷時幾個月,終於錄完Android binder,如釋重負
    今日更新:第8課第6節_Binder系統_JAVA實現_內部機制_Server端第8課第7節_回看SystemServer_硬體訪問服務及課後作業答案然後就是輸入、輸出系統;有了輸入輸出我們就可以從0移整個android了然後就是android文件系統
  • Android Systrace 基礎知識(10) - Binder 和鎖競爭解讀
    1/3:驅動篇[13]理解 Android Binder 機制 2/3:C++層[14]理解 Android Binder 機制 3/3:Java 層[15]「之所以要單獨講 Systrace 中的 Binder 和鎖,是因為很多卡頓問題和響應速度的問題,是因為跨進程 binder 通信的時候,鎖競爭導致 binder 通信事件變長
  • 圖文詳解 Android Binder跨進程通信的原理
    註:傳統的跨進程通信需拷貝數據2次,但 Binder機制只需1次,主要是使用到了內存映射,具體下面會詳細說明2.5 內存映射3. Binder 跨進程通信機制 模型3.1 模型原理圖Binder 跨進程通信機制 模型 基於 Client-Server 模式
  • 談談你對 binder 的理解?
    10k面試官️:談談你對 binder 的理解😎:binder 是用來跨進程通信的,可以分為 client、server、binder 驅動以及 service manager 四部分。面試官:Intent 傳參有大小限制,這跟 binder 有關係嗎?😨:嗯... 應該有關係吧面試官:binder 是如何限制這個大小的?😨:這個不了解,我還沒有深入看過相關源碼。
  • Android之Binder底層原理詳解必讀
    Android為什麼使用Binder作為主要進程間通訊機制?        1、安全性:Binder機制從協議本身就支持對通信雙方做身份校檢,安全性高。asBinder(){return this;}@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException{switch (code){case INTERFACE_TRANSACTION
  • 如何讓你的App永遠在後臺存活:對Android進程守護、鬧鐘後臺被殺死的研究
    123個微信小程序源碼分享(附下載)[乾貨]2017已來,最全面試總結——這些Android面試題你一定需要原文:http://blog.csdn.net方法1:在原生的Android系統上使用AlarmManager方法2:通過AIDL實現雙進程守護機制方法3:MarsDaemon第三方庫,實現進程常駐方法4:通過AppWiget,android桌面小組件保持進程的運行
  • 寫給 Android 應用工程師的 Binder 原理剖析
    四大組件底層的通信機制是怎樣的?AIDL 內部的實現原理是什麼?插件化編程技術應該從何學起?等等…這些問題的背後都與 Binder 有莫大的關係,要弄懂上面這些問題理解 Bidner 通信機制是必須的。
  • 三年經驗 Android 開發面經總結
    在下2017年畢業,目前從事android開發工作已經3年啦,前段時間剛完成一次跳槽,面試了幾家公司,將一些面試經驗分享給大家,希望對大家有所幫助。簡歷首先是簡歷,一般找一個模板,填寫掌握的技能和項目經歷即可。
  • 三年啦,跳槽成功的Android開發面經總結!
    在下2017年畢業,目前從事android開發工作已經3年啦,前段時間剛完成一次跳槽,面試了幾家公司,將一些面試經驗分享給大家,希望對大家有所幫助。首先是簡歷,一般找一個模板,填寫掌握的技能和項目經歷即可。
  • Android-HIDL實例解析
    設計 HIDL 這個機制的目的,主要是想把**框架(framework)**與 HAL 進行隔離,使得框架部分可以直接被覆蓋、更新,而不需要重新對 HAL 進行編譯。HAL 的部分將會放在設備的 /vendor 分區中,並且是由設備供應商(vendors)或 SOC 製造商來構建。
  • 這套1307頁的阿里、騰訊等大廠Android面試真題解析火了!
    內容概要:包括 Handler、Activity相關、Fragment、service、布局優化、AsyncTask相關、Android 事件分發機制、 Binder、Android 高級必備 :AMS,WMS,PMS、Glide、 Android 組件化與插件化等面試題和技術棧!
  • 學Android 這麼久,intent傳遞數據最大多少呢?
    其實不是的,我們可以在Manifest.xml中設置android:process屬性來為Activity, Service等指定單獨的進程,所以Activity的startActivity方法是原生支持跨進程通信的。接下來簡單分析下binder機制。
  • 用Binder原理徹底徵服大廠面試官吧
    作者: 劉望舒原文: http://liuwangshu.cn/framework/binder/3-addservice.html這是後廠村碼農的第 131篇原創分享前言在上一篇文章中,我們學習了ServiceManager中的Binder機制,有一個問題由於篇幅問題沒有講完,那就是MediaPlayerService是如何註冊的。
  • Binder Driver缺陷導致定屏的實戰分析
    一、背景知識點解決此問題所涉及到的基礎知識點有:Trace、CPU調度、Ramdump推導、Crash工具、GDB工具、Ftrace, 尤其深入理解binder IPC機制。1.1 工具簡介Trace:分析死鎖問題的最基本的技能,通過kill -3可生成相應的traces.txt文件,裡面記錄著當前時刻系統各線程 所處在的調用棧。
  • 可能是目前最全的《Android面試題及解析》(379頁)
    趁著這段時間,小夥伴們可以參考這份可能是市面上最全面的安卓面試題解析大全!從基礎到架構進階,包含了騰訊、百度、小米、阿里、樂視、美團、58、獵豹、360、新浪、搜狐等一線網際網路公司面試被問到的題目,涵蓋了初中高級安卓技術點。文章中所列主要為大綱部分,詳細內容可以在文末自行獲取哈!
  • Android四大組件的onCreate/onReceiver方法中Thread.sleep(),會產生幾個ANR?
    是否了解四大組件的onCreate/onReceive執行時所在線程可能涉及如何監聽ANR的產生可能涉及如何分析ANR文件考察的知識點ANR的產生場景ANR的觸發機制是否了解四大組件的onCreate/onReceive執行時所在線程Android文件監聽機制,Handler
  • Android權限機制與適配經驗
    一、概要Android M已經發布一段時間了,市面上很多應用都已經適配Android M。然而,同期的iOS對於權限的處理會更加靈活,權限的授予並不是在安裝時,而是在APP運行時,用戶可以根據自身的需要,決定是否授予APP某一權限,同時,用戶也可以很方便回收授予的權限。顯然,動態權限管理的機制,對於用戶的隱私保護是更加適用的,Android過於簡單的權限機制也受到了不少人的吐槽。終於,Android6.0也發布了動態權限的機制。
  • 【Android】一次面試總結
    如何打多渠道包在AndroidMainfest.xml配置相應的渠道 <meta-data android:value="UMENG_CHANNEL"              android:name="${UMENG_CHANNEL_VALUE}"/>  <!
  • 熬夜整理了一份Android高頻面試題集錦+開源框架實戰PDF
    內容是從基礎到架構進階,包含了騰訊、百度、小米、阿里、樂視、美團、58、獵豹、360、新浪、搜狐等一線網際網路公司面試被問到的題目,涵蓋了初中高級安卓技術點。如果你熟練掌握本文中列出的知識點,相信將會大大增加你通過前兩輪技術面試的機率!這些內容都供大家參考,互相學習。