您好,登錄后才能下訂單哦!
這篇文章主要介紹“ANDROID BINDER通信架構(gòu)怎么掌握”,在日常操作中,相信很多人在ANDROID BINDER通信架構(gòu)怎么掌握問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”ANDROID BINDER通信架構(gòu)怎么掌握”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
在這個過程中, 常見的幾個BR_命令:
BR_TRANSACTION_COMPLETE: binder驅(qū)動收到BC_TRANSACTION事件后的應(yīng)答消息; 對于oneway transaction,當收到該消息,則完成了本次Binder通信;
BR_DEAD_REPLY: 回復(fù)失敗,往往是線程或節(jié)點為空. 則結(jié)束本次通信Binder;
BR_FAILED_REPLY:回復(fù)失敗,往往是transaction出錯導(dǎo)致. 則結(jié)束本次通信Binder;
BR_REPLY: Binder驅(qū)動向Client端發(fā)送回應(yīng)消息; 對于非oneway transaction時,當收到該消息,則完整地完成本次Binder通信;
規(guī)律: BC_TRANSACTION + BC_REPLY = BR_TRANSACTION_COMPLETE + BR_DEAD_REPLY + BR_FAILED_REPLY
處于剩余的BR_命令.
binder_write_read結(jié)構(gòu)體用來與Binder設(shè)備交換數(shù)據(jù)的結(jié)構(gòu), 通過ioctl與mDriverFD通信,是真正與Binder驅(qū)動進行數(shù)據(jù)讀寫交互的過程。 ioctl()方法經(jīng)過syscall最終調(diào)用到Binder_ioctl()方法.
[→ Binder.c]
由【小節(jié)2.11】傳遞過出來的參數(shù) cmd=BINDER_WRITE_READ
首先,根據(jù)傳遞過來的文件句柄指針獲取相應(yīng)的binder_proc結(jié)構(gòu)體, 再從中查找binder_thread,如果當前線程已經(jīng)加入到proc的線程隊列則直接返回,如果不存在則創(chuàng)建binder_thread,并將當前線程添加到當前的proc.
當返回值為-ENOMEM,則意味著內(nèi)存不足,往往會出現(xiàn)創(chuàng)建binder_thread對象失敗;
當返回值為-EINVAL,則意味著CMD命令參數(shù)無效;
此時arg是一個binder_write_read
結(jié)構(gòu)體,mOut
數(shù)據(jù)保存在write_buffer,所以write_size>0,但此時read_size=0。首先,將用戶空間bwr結(jié)構(gòu)體拷貝到內(nèi)核空間,然后執(zhí)行binder_thread_write()操作.
不斷從binder_buffer所指向的地址獲取cmd, 當只有BC_TRANSACTION
或者BC_REPLY
時, 則調(diào)用binder_transaction()來處理事務(wù).
發(fā)送的是BC_TRANSACTION時,此時reply=0。
主要功能:
查詢目標進程的過程: handle → binder_ref → binder_node → binder_proc
將BINDER_WORK_TRANSACTION
添加到目標隊列target_list, 首次發(fā)起事務(wù)則目標隊列為target_proc->todo
, reply事務(wù)時則為target_thread->todo
; oneway的非reply事務(wù),則為target_node->async_todo
.
將BINDER_WORK_TRANSACTION_COMPLETE
添加到當前線程的todo隊列
此時當前線程的todo隊列已經(jīng)有事務(wù), 接下來便會進入binder_thread_read()來處理相關(guān)的事務(wù).
當收到的是BINDER_WORK_TRANSACTION_COMPLETE, 則將命令BR_TRANSACTION_COMPLETE寫回用戶空間.
當收到的是BINDER_WORK_TRANSACTION命令, 則將命令BR_TRANSACTION或BR_TRANSACTION寫回用戶空間.
執(zhí)行完binder_thread_write方法后, 通過binder_transaction()首先寫入BINDER_WORK_TRANSACTION_COMPLETE
寫入當前線程.
這時bwr.read_size > 0, 回到binder_ioctl_write_read方法, 便開始執(zhí)行binder_thread_read();
在binder_thread_read()方法, 將獲取cmd=BR_TRANSACTION_COMPLETE, 再將cmd和數(shù)據(jù)寫回用戶空間;
一次Binder_ioctl完成,接著回調(diào)用戶空間方法talkWithDriver(),并且剛才的數(shù)據(jù)寫入mIn
.
這時mIn有可讀數(shù)據(jù), 回到waitForResponse()方法,完成BR_TRANSACTION_COMPLETE過程.
再回退到transact()方法, 對于oneway的操作, 這次Binder通信便完成, 否則還是要等待Binder服務(wù)端的返回.
對于startService過程, 顯然沒有指定oneway的方式,那么發(fā)起者進程還會繼續(xù)停留在waitForResponse()方法,等待收到BR_REPLY消息. 由于在前面binder_transaction過程中,除了向自己所在線程寫入了BINDER_WORK_TRANSACTION_COMPLETE
, 還向目標進程(此處為system_server)寫入了BINDER_WORK_TRANSACTION
命令. 而此時system_server進程的binder線程一旦空閑便是停留在binder_thread_read()方法來處理進程/線程新的事務(wù), 收到的是BINDER_WORK_TRANSACTION
命令, 經(jīng)過binder_thread_read()后生成命令BR_TRANSACTION
.同樣的流程.
接下來,從system_server
的binder線程一直的執(zhí)行流: IPC.joinThreadPool –> IPC.getAndExecuteCommand() → IPC.talkWithDriver() ,但talkWithDriver收到事務(wù)之后, 便進入IPC.executeCommand(), 接下來,從executeCommand說起.
對于oneway的場景, 則到此全部結(jié)束.
對于非oneway, 也就是需要reply的通信過程,則向Binder驅(qū)動發(fā)送BC_REPLY命令
[→ Binder.cpp ::BBinder ]
4.4 JavaBBinder.onTransact
[→ android_util_Binder.cpp]
還記得AndroidRuntime::startReg過程嗎, 其中有一個過程便是register_android_os_Binder(),該過程會把gBinderOffsets.mExecTransact便是Binder.java中的execTransact()方法.詳見見Binder系列7—framework層分析文章中的第二節(jié)初始化的過程.
另外,此處mObject是在服務(wù)注冊addService過程,會調(diào)用writeStrongBinder方法, 將Binder對象傳入了JavaBBinder構(gòu)造函數(shù)的參數(shù), 最終賦值給mObject. 在本次通信過程中Object為ActivityManagerNative對象.
此處斗轉(zhuǎn)星移, 從C++代碼回到了Java代碼. 進入AMN.execTransact, 由于AMN繼續(xù)于Binder對象, 接下來進入Binder.execTransact
[Binder.java]
當發(fā)生RemoteException, RuntimeException, OutOfMemoryError, 對于非oneway的情況下都會把異常傳遞給調(diào)用者.
[→ ActivityManagerNative.java]
4.7 AMS.startService
歷經(jīng)千山萬水, 總算是進入了AMS.startService. 當system_server收到BR_TRANSACTION的過程后, 再經(jīng)歷一個類似的過程,將事件告知app所在進程service啟動完成.過程基本一致,此處就不再展開.
到此,關(guān)于“ANDROID BINDER通信架構(gòu)怎么掌握”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。