由于嘴賤闯第,立了個(gè)flag...
And thanks for this flag ...
To be continued...
Aidl
1)快速上手
-
JavaBean
首先,先寫一個(gè)JavaBean備用
PS:該文件不要同AIDL文件放置同一個(gè)包下睬棚,否是運(yùn)行會(huì)提示找不到該類
Book.java -
JavaBean.aidl
然后在開始我們新建我們的AIDL文檔前驯绎,先新建一個(gè)與上面JavaBean同名的AIDL文件檀训,既Book.aidl,并在其中聲明我們的Book對(duì)象
Book.aidl
并且該文件需要同上面的JavaBean文件在AIDL下放至于相同的位置淑蔚,應(yīng)該是IDE 解析的時(shí)候會(huì)自動(dòng)去相同路徑下查詢,算是一種映射吧愕撰,因?yàn)榇龝?huì)Sync項(xiàng)目后source下會(huì)自動(dòng)生成java代碼刹衫,import引用的是aidl路徑下的Book.aidl,而這則是由實(shí)現(xiàn)了Parcelable的Book.java映射過去的搞挣,所以這中間路徑需保持一致带迟,不然鎖鏈就斷了 (待研究)
278511509262463_.pic_hd.jpg -
AIDL
最后我們開始新建真正所要用的AIDL對(duì)象:BookManager.aidl,并在其中寫入接口函數(shù)
在我這小菜鳥現(xiàn)有的理解中囱桨,可以暫且將AIDL作為接口來看待仓犬,但不同于接口的是
要注意:- 在AIDL文件中使用自定義的JavaBean對(duì)象(或非默認(rèn)數(shù)據(jù)類型),都必須要在文件中顯式地導(dǎo)入進(jìn)來舍肠,正如注釋所寫的:在此用導(dǎo)入語句來聲明任何非默認(rèn)類型搀继;
- 并且別忘了對(duì)象參數(shù)的類型定義,既in/out/inout
不然會(huì)導(dǎo)致第四步的Sync Project的時(shí)候報(bào)錯(cuò)......(慘痛經(jīng)歷)
Aidl -
Sync Project with Gradle Files
至此翠语,在AS中點(diǎn)擊Sync Project同步下項(xiàng)目叽躯,編譯器將自動(dòng)根據(jù)我們的AIDL文件生成同名的.java文件(若這里忘了同步,則在后續(xù)代碼的調(diào)用將不會(huì)有快捷提示了)
生成的.java路徑(Project模式下):
image.png -
Service
由于我們的AIDL是跟Service配合使用的肌括,所以我們就接著在Service中創(chuàng)建并調(diào)用点骑,具體如下
由于AIDL也是Binder的子類(有點(diǎn)忘了,我后續(xù)確認(rèn)下嘿嘿嘿)谍夭,所以只要通過binder新建個(gè)aidl的對(duì)象畔况,然后自然就會(huì)重寫我們aidl里的方法(這也是為什么我暫且將其作為接口看待的原因)
Service
然后記得在onBind()函數(shù)中將上述myBinder返回即可,至此Service部分就寫完了
-
Activity
最后是我們的Activity慧库,Activity部分也挺簡(jiǎn)單的
我們只需要在onServiceConnected()中通過調(diào)用AIDL.Stub.asInterface()跷跪,并將該方法中的IBinder型參數(shù)傳入即可,這樣我們就獲取到了我們的AIDL對(duì)象齐板,而后續(xù)的事也就是通過該對(duì)象來調(diào)用之前寫在里面的方法罷了
Activity
-
結(jié)果
image.png
2)添加監(jiān)聽
-
新建監(jiān)聽aidl文件:BookListener.aidl吵瞻,并在其中完善監(jiān)聽接口
BookListener.aidl -
在BookManager.aidl中也添加注冊(cè)和解綁監(jiān)聽的方法,記得需要顯式導(dǎo)包
BookManager.aidl -
Service中重寫AIDL中兩個(gè)新添加的方法以實(shí)現(xiàn)注冊(cè)和解綁甘磨,并且模擬添加書籍
重寫方法
(模擬添加書籍可參照開發(fā)藝術(shù)探索P78)
模擬持續(xù)添加book
-
Activity中獲取BookListener的對(duì)象橡羞,并重寫方法打印,然后記得調(diào)用bookManager.registerListener()即可
2017-10-27-09-36-41.jpg
2017-10-27-09-37-06.jpg -
結(jié)果:
可以從log里看到济舆,當(dāng)Activity銷毀調(diào)用unregisterListener()時(shí)卿泽,無法找到之前注冊(cè)的listener
Log
PS:若Service和Activity在同一個(gè)進(jìn)程的情況下,則不會(huì)有上述現(xiàn)象
3)使用RemoteCallbackList
由于我們的Service和Activity是在兩個(gè)進(jìn)程,而對(duì)象不能跨進(jìn)程傳輸签夭,而多進(jìn)程跨進(jìn)程的話齐邦,無法調(diào)取到同一對(duì)象,因?yàn)閷?duì)象不能跨進(jìn)程傳輸第租,所以Binder會(huì)把客戶端傳遞過來的對(duì)象重新轉(zhuǎn)換生成一個(gè)新的對(duì)象措拇,
故若多進(jìn)程時(shí)解綁,需要使用RemoteCallbackList
-
將listenerList類型從List改為RemoteCallbackList
RemoteCallbackList -
重寫binder中的注冊(cè)和解綁函數(shù)
修改注冊(cè)解綁方法
需要注意的是RemoteCallbackList的size可以通過beginBroadcast()獲取慎宾,但需要在調(diào)用后丐吓,調(diào)用finishBroadcast()
RemoteCallbackList.begin -
結(jié)果
Log
項(xiàng)目地址:
遺留
- AIDL里的in,out趟据,inout三種類型
- 由于上面只是知其然券犁,還需要看官方文檔知其所以然下
Refrence
- 《Android開發(fā)藝術(shù)探索》