AIDL挖坑

1. android中得IPC方式

  1. bundle
    1. 由于bundle實(shí)現(xiàn)了parcelable借口,且四大組件中得其中三個(gè)(activity,service,receive)都支持在intent中傳遞bundle數(shù)據(jù),比較方便實(shí)現(xiàn)不同的進(jìn)程間傳遞數(shù)據(jù)
  2. 使用文件共享
    1. 文件共享也是一種不錯(cuò)的進(jìn)程間通信方式,兩個(gè)進(jìn)程通過讀寫同一個(gè)文件來交換數(shù)據(jù),比如A進(jìn)程中把數(shù)據(jù)寫入文件,B進(jìn)程通過讀取這個(gè)文件來獲取數(shù)據(jù)。但是這種方式也是又一定局限性的,比如并發(fā)讀寫的問題會(huì)導(dǎo)致我們讀出的數(shù)據(jù)不是最新的,因此要避免并發(fā)讀寫的發(fā)生或者考慮使用線程同步來限制多個(gè)線程的讀寫操作。基于這樣的問題,文件共享方式適合對(duì)數(shù)據(jù)同步要求不高的進(jìn)程之間進(jìn)行通信。
  3. 使用Messenger
    1. Messenger是一種輕量級(jí)的IPC方案,它的底層實(shí)現(xiàn)是AIDL,通過Messenger可以在不同進(jìn)程中傳遞Message對(duì)象,在Message中放入我們需要傳遞的數(shù)據(jù)就可以輕松實(shí)現(xiàn)數(shù)據(jù)在進(jìn)程間傳遞了。
  4. 使用AIDL
    1. Messenger是以串行的方式處理客戶端的請(qǐng)求,如果有大量的請(qǐng)求同時(shí)發(fā)送到服務(wù)端,服務(wù)端仍然只能一個(gè)一個(gè)處理,此時(shí)Messenger就不大合適了,同時(shí)Messenger的作用是為了傳遞消息,且只能傳遞Bundle支持的數(shù)據(jù)類型,很多時(shí)候需要跨進(jìn)程調(diào)用服務(wù)端的方法,這時(shí)候可以實(shí)用AIDL來實(shí)現(xiàn)跨進(jìn)程的方法調(diào)用。AIDL也是Messenger的底層實(shí)現(xiàn),因此Messenger本質(zhì)上也是AIDL,只不過系統(tǒng)作了封裝。

2. 原理

  1. 在app層:binder是客戶端和服務(wù)端通信的媒介,當(dāng)bindservice的時(shí)候,服務(wù)端會(huì)返回一個(gè)包含了服務(wù)端業(yè)務(wù)調(diào)用的binder對(duì)象,通過這個(gè)binder對(duì)象,客戶端就可以獲取到服務(wù)端提供的服務(wù)或者數(shù)據(jù),這里面的服務(wù)包含了普通服務(wù)和基于AIDL的服務(wù);
  2. 在framework層,binder是各種Manger(ActivityManger,windowManger等)和響應(yīng)xxxMangerService的橋梁;
  3. 在native層.binder是創(chuàng)建了ServiceManger以及BpBinder/BBinder模型,搭建binder的橋梁;

3. 具體使用

1. 客戶端
  1. 在main文件夾下建aidl文件,這個(gè)需要特別注意在客戶端也要建立相同包名,文件名的aidl文件;
  2. 在aidl中定義在服務(wù)端要實(shí)現(xiàn)的方法,此時(shí)注意aidl語法接受的參數(shù)類型;
  3. 新建完成之后點(diǎn)擊構(gòu)建,在build->generated->source->aidl->debug->包名->就會(huì)生成一個(gè)與剛剛新建的同名的接口文件;
  4. 以上部分與服務(wù)端同樣,做相同的工作,-------------
  5. 客戶端實(shí)現(xiàn)具體的邏輯,連接服務(wù),實(shí)現(xiàn)通訊
2. 服務(wù)端
  1. 前三部是與客戶端相同,
  2. 實(shí)現(xiàn)stub操作,獲取到一個(gè)Ibinder對(duì)象,實(shí)現(xiàn)aidl文件中定義的方法;
3. 解析生成的aidl.java文件
  1. 簡單的分類對(duì)于生成的aidl文件

     IRemoteAidl
     Stub abstract extend IBinder implements IRemoteAidl 
         poxy implements IRemoteAidl
             poxy()
             asBinder()
             getInterfaceDescriptor()
             add()
         Stub()  IBinder
         asInterface() IRemoteAidl
         asBinder() IBinder
         onTransact()
     add()
    
  2. 對(duì)于客戶端只需要獲取到IRemoteAidl對(duì)象來調(diào)用add

  3. 對(duì)于服務(wù)端需要獲取到Ibinder對(duì)象來做返回;

  4. 可能大家也注意點(diǎn) Proxy 這里是private權(quán)限的,外部是無法訪問的,但這里是 Android 有意為之,拋出了 asInterface 方法,這樣避免了對(duì) Proxy可能的修改。

  5. Proxy 是寫入?yún)?shù),讀取值;Stub 是讀取參數(shù),寫入值,剛好也就是從客戶端到服務(wù)端的步驟,poxy,寫入?yún)?shù),stub獲取到參數(shù)經(jīng)過處理然后寫入,poxy就可以讀取到值了;

4. 常見的問題

  1. 只有一個(gè)service,不能安裝應(yīng)用的情況Error running app: Default ActivityNot Found。;
    • 默認(rèn)情況下安裝默認(rèn)設(shè)置Lunche工程時(shí)是需要Activity的
    • Run configurations ->general->lunch:nothing
  2. 客戶端和服務(wù)端必須擁有相同的aidl文件的問題(包括包名,文件名都要相同),包括方法的定義順序等都必須要相同,不然會(huì)出現(xiàn)Java.lang.SecurityException: Binder invocation to an incorrect interface 這個(gè)錯(cuò)誤。
  3. service 的注冊(cè)配置的問題;service要和client運(yùn)行在不同的進(jìn)程中,所以一定要記得去配置procress屬性;
  4. service的啟動(dòng)問題;
    1. 使用bindService的方式去啟動(dòng)
  5. 這個(gè)地方涉及到安卓中開啟多進(jìn)程的方式:如果你想在一個(gè)應(yīng)用中使用多個(gè)進(jìn)程,通過清單文件給四大組件添加android:process屬性,就可以很方便的開啟多進(jìn)程.


    AndroidManifest.png
    1. 如圖開啟了三個(gè)進(jìn)程:默認(rèn)進(jìn)程是MainActivity
    2. $ adb shell ps | grep com.szysky 你可以直接使用adb shell ps這會(huì)把系統(tǒng)所有進(jìn)程展示出來,
    3. 你可能已經(jīng)發(fā)現(xiàn)在創(chuàng)建新進(jìn)程的時(shí)候使用兩種不同的方式
      1. 當(dāng)以:開頭的進(jìn)程,屬于當(dāng)前應(yīng)用的私有進(jìn)程,其他應(yīng)用的組件不可以和它跑在同一個(gè)進(jìn)程
      2. 當(dāng)不以:開頭,那么進(jìn)程屬于全局進(jìn)程,其他應(yīng)用通過ShareUID方法可以和它跑在同一個(gè)進(jìn)程
      3. Android系統(tǒng)會(huì)為每一個(gè)應(yīng)用分配唯一的UID. 相同UID的應(yīng)用才能共享數(shù)據(jù). 但是兩個(gè)應(yīng)用通過ShareUID跑在同一個(gè)進(jìn)程是有要求的. 除了具有相同的ShareUID并且還要簽名相同才可以. 這時(shí)如果不在同一進(jìn)程他們之間可以共享data目錄,組件信息等. 如果還在同一進(jìn)程, 那么他們還能共享內(nèi)存數(shù)據(jù).
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容