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


















