AndroidStudio下使用 AIDL 構(gòu)建跨進(jìn)程 Service( 詳細(xì)代碼貼圖 ), 填補(bǔ)網(wǎng)上的大多數(shù)坑

現(xiàn)在百度一下 AIDL/跨進(jìn)程 Service, 文章一大堆, 然而都是千篇一律, 存在很多同樣模棱兩可的坑, 而且沒有AndroidStudio的最終目錄樹, 做起來(lái)還是有各種各樣的不順.

先說(shuō)一下幾個(gè)網(wǎng)上模棱兩可的問(wèn)題:

  1. 客戶端和服務(wù)端不用必須兩個(gè)apk;
  2. AndroidManifest 聲明的 service 的 progress 不用必須寫 :remote, 這里是寫進(jìn)程的名字, 可以寫任意字符;
  3. java.lang.SecurityException: Binder invocation to an incorrect interface 錯(cuò)誤真不一定是因?yàn)榭蛻舳撕头?wù)端的包名不一致導(dǎo)致的, 有可能是實(shí)例化AIDL接口的時(shí)候不是實(shí)現(xiàn)的 XXX.Stub

源碼放在了github: https://github.com/YouCii/LearnApp

下面說(shuō)下基本的實(shí)現(xiàn)流程


AIDL最簡(jiǎn)單實(shí)現(xiàn)流程

先寫服務(wù)端

  1. 新建AIDL文件

    新建完成后會(huì)在src/main下生成aidl目錄, 修改生成的aidl文件, 寫入自己的接口方法
  2. 編譯程序, AS 會(huì)在 build 目錄中自動(dòng)生成 aidl 對(duì)應(yīng)的 java 實(shí)現(xiàn)
  3. 寫好遠(yuǎn)程服務(wù)

    別忘了在 AndroidManifest中聲明

客戶端

  1. 把所有 aidl 文件及其包名全部復(fù)制到客戶端里, 要保證包名一致, 不過(guò)有人奇怪怎么能兩個(gè)apk同一個(gè)包名呢? 可以這樣做(這里的圖片使用了后面加入ServiceData/ISocketStateListener.aidl的情況, 請(qǐng)忽略這幾個(gè)文件)
  2. 實(shí)現(xiàn)客戶端執(zhí)行代碼, 這里簡(jiǎn)化了無(wú)關(guān)代碼, 只需要 bindService 時(shí) 傳入創(chuàng)建的 connection, 獲取到 aidl 對(duì)應(yīng)的 java 對(duì)象即可

客戶端和服務(wù)端在一個(gè)apk里
網(wǎng)上都沒有提過(guò)這種情況, 其實(shí)是可以的, 根本不用拷貝aidl文件, 還要保證包名必須一致. 這種方式的唯一apk的結(jié)構(gòu)樹如下(這里的圖片使用了后面加入ServiceData/ISocketStateListener.aidl的情況, 請(qǐng)忽略這幾個(gè)文件)


更多的使用

AIDL默認(rèn)只能傳遞基本類型, 如果想傳遞自己的對(duì)象, 需要利用 Parcelable

如果想監(jiān)聽服務(wù)端, 需要再創(chuàng)建一個(gè) aidl 接口

然后在服務(wù)端實(shí)現(xiàn)接口, 客戶端內(nèi)調(diào)用 aidl 對(duì)應(yīng)的 java 內(nèi)的方法即可
服務(wù)端(請(qǐng)忽略代碼里的錯(cuò)誤, 這是為了演示修改出來(lái)的)

客戶端


碰見的各種坑

  • 報(bào)錯(cuò) Error:Execution failed for task ':app:compileDebugAidl'.


    原因是包名不匹配, 一定要注意aidl自己所在的包名, 以及引用的其他 aidl 所在的包名, 如果寫錯(cuò)了as不會(huì)報(bào)錯(cuò), 編譯的時(shí)候才有問(wèn)題, 一定要仔細(xì)檢查.

  • 自動(dòng)生成的AIDL找不到Parcelable自定義對(duì)象問(wèn)題, 原因在于 aidl 文件和 Parcelable對(duì)象的包名不一致, 一定要保證兩者所在的包名一模一樣

  • 報(bào)錯(cuò) java.lang.SecurityException: Binder invocation to an incorrect interface. 這里有兩種情況

    1. 客戶端和服務(wù)端的包名不一致導(dǎo)致, 如果是客戶端和服務(wù)端分開的實(shí)現(xiàn)形式, 建議直接復(fù)制服務(wù)端的 aidl 根目錄. 請(qǐng)參考上面的目錄樹;
    2. onBind中返回aidl對(duì)象return pitPatAidlStub; 或者 調(diào)用binder的設(shè)置接口方法aidlBinder.setSocketStateListener時(shí), 錯(cuò)誤的實(shí)例化了 new IPitPatAidlInterface()而不是 new IPitPatAidlInterface.Stub(), 實(shí)例化了new ISocketStateListener() 而不是 new ISocketStateListener.Stub()

其他說(shuō)明

  • 其中還好奇試了下, 使用 啟動(dòng)同一進(jìn)程service的方式 啟動(dòng) 聲明了progress的service, 結(jié)果報(bào)錯(cuò): proxy can`t cast to...的錯(cuò)誤.
  • aidl接口傳參時(shí)寫的 in / out / inout 修飾符 也要知道, 否則會(huì)出現(xiàn)數(shù)據(jù)不同步的問(wèn)題. in 代表客戶端傳入服務(wù)端, 如果在服務(wù)端修改 in 修飾的變量時(shí), 客戶端的變量不會(huì)更改, 修改為 out 修飾時(shí)服務(wù)端的變動(dòng)會(huì)同步給客戶端, 但是服務(wù)端拿到的對(duì)象內(nèi)的參數(shù)會(huì)是空的, 可以使用inout來(lái)同時(shí)滿足; 注意使用out或者inout修飾時(shí), 自定義的pacelable對(duì)象不僅僅只實(shí)現(xiàn)writeToParcel, 還要手寫 fun readFromParcel(parcel: Parcel) 方法
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末抛猫,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子脱盲,更是在濱河造成了極大的恐慌邑滨,老刑警劉巖日缨,帶你破解...
    沈念sama閱讀 216,919評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钱反,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)面哥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門哎壳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人尚卫,你說(shuō)我怎么就攤上這事归榕。” “怎么了吱涉?”我有些...
    開封第一講書人閱讀 163,316評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵刹泄,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我怎爵,道長(zhǎng)特石,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,294評(píng)論 1 292
  • 正文 為了忘掉前任鳖链,我火速辦了婚禮姆蘸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘芙委。我一直安慰自己逞敷,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評(píng)論 6 390
  • 文/花漫 我一把揭開白布灌侣。 她就那樣靜靜地躺著推捐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪侧啼。 梳的紋絲不亂的頭發(fā)上玖姑,一...
    開封第一講書人閱讀 51,245評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音慨菱,去河邊找鬼焰络。 笑死,一個(gè)胖子當(dāng)著我的面吹牛符喝,可吹牛的內(nèi)容都是我干的闪彼。 我是一名探鬼主播,決...
    沈念sama閱讀 40,120評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼协饲,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼畏腕!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起茉稠,我...
    開封第一講書人閱讀 38,964評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤描馅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后而线,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體铭污,經(jīng)...
    沈念sama閱讀 45,376評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡恋日,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了嘹狞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片岂膳。...
    茶點(diǎn)故事閱讀 39,764評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖磅网,靈堂內(nèi)的尸體忽然破棺而出谈截,到底是詐尸還是另有隱情,我是刑警寧澤涧偷,帶...
    沈念sama閱讀 35,460評(píng)論 5 344
  • 正文 年R本政府宣布簸喂,位于F島的核電站,受9級(jí)特大地震影響燎潮,放射性物質(zhì)發(fā)生泄漏娘赴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評(píng)論 3 327
  • 文/蒙蒙 一跟啤、第九天 我趴在偏房一處隱蔽的房頂上張望诽表。 院中可真熱鬧,春花似錦隅肥、人聲如沸竿奏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)泛啸。三九已至,卻和暖如春秃症,著一層夾襖步出監(jiān)牢的瞬間候址,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工种柑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留岗仑,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,819評(píng)論 2 370
  • 正文 我出身青樓聚请,卻偏偏與公主長(zhǎng)得像荠雕,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子驶赏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評(píng)論 2 354