android AIDL跨應用通信,實現(xiàn)回調監(jiān)聽
android IPC通信可以使用很多方式實現(xiàn),包括Messager、Handler、Provider、AIDL、Socket、bundle,下面是引用的網(wǎng)上的一張圖片:

?????? 總結一下:其中Bundle是用于進程間的通信,其他的都可用于進程間或者跨進程通信,Messager由于支持的數(shù)據(jù)格式有限,所以只能進行簡單的數(shù)據(jù)通信,Socket實現(xiàn)起來會比較復雜,但是功能還是很強大的。
??????? 所以最后,AIDL是最合適的選擇了,實現(xiàn)起來也很方便,在Android studio 中實現(xiàn)了aidl文件,build之后會在build/generated/source/aidl/debug目錄下看到aidl對應的java文件,這個是系統(tǒng)自動幫我們完成的,他的源碼也不難,后續(xù)會詳細講解。
??????? 我們大多數(shù)的需求應該是要傳遞各種各樣的對象或者集合,而不是哪些基本的數(shù)據(jù),下面我們一步步來實現(xiàn)。下面是我的服務端的整體結構:

首先,我們創(chuàng)建一個bean類,Book.java,用于后續(xù)IPC通信傳遞的對象。

?????? 這里我實現(xiàn)了Parcelable接口,我們知道,要實現(xiàn)進程間通信,必須實現(xiàn)序列化,實現(xiàn)方式有兩種:Parcelable和Serialazable,這里引用網(wǎng)上官方的說法解釋一下:
?????? Serializable的作用是為了保存對象的屬性到本地文件、數(shù)據(jù)庫、網(wǎng)絡流、rmi以方便數(shù)據(jù)傳輸,當然這種傳輸可以是程序內的也可以是兩個程序間的。而Android的Parcelable的設計初衷是因為Serializable效率過慢,為了在程序內不同組件間以及不同Android程序間(AIDL)高效的傳輸數(shù)據(jù)而設計,這些數(shù)據(jù)僅在內存中存在,Parcelable是通過IBinder通信的消息的載體。
??? ?? 通過上面的解釋我們應該知道了,Parcelable接口采用Binder作為通信方式,速度是要快一些的,而Serializable在實現(xiàn)上很簡單只需要實現(xiàn)接口即可,不用像Parcelable那樣還得自己來實現(xiàn)里面的方法。
???????? 實現(xiàn)了bean類之后,我們可以開始編寫aidl文件了,我們在main目錄下單獨創(chuàng)建一個aidl的文件夾,方便查看,然后創(chuàng)建Book.aidl文件。這里相當于一個媒介,是Book類在AIDL中的聲明,不然我們是無法直接使用到Book類的。
??????????????? 這個實現(xiàn)很簡單,就聲明一下Book類即可。接下來是最重要的aidl文件的實現(xiàn)IBookInterface.aidl,服務端后面要實現(xiàn)的方法都是在該類中定義。

?????? 我這里實現(xiàn)了addBook、getBookList以及后面兩個注冊與解注冊的方法,就是我們熟悉的監(jiān)聽者模式,監(jiān)聽是否添加了新書,然后主動回調給監(jiān)聽者。IOnNewBookArrivedListener.aidl文件實現(xiàn)的也很簡單,就是一個監(jiān)聽方法:

??????? 然后我們把module build一下,完成后我們去build/generated/source/aidl/debug/目錄下,會發(fā)現(xiàn)我們剛才實現(xiàn)的adil類在這里又出現(xiàn)了,這個是系統(tǒng)幫我們自動實現(xiàn)的方法。
???????? 接下來,我們實現(xiàn)服務端最重要的類,BookServer.java,它是一個服務類,繼承了Server,Server就不多說了。下面看一下這個類的具體實現(xiàn):


?????? 這里就是具體的實現(xiàn)了,其中最主要的就是MyBinder類,在這里面我們實現(xiàn)了aidl的方法。注意,這里我使用的是RemoteCallbackList,這個類我也是第一次使用,是專用于跨進程回調的類,使用起來很方便。大家看一下我各個方法的實現(xiàn),其實都很簡單,因為最復雜的工作系統(tǒng)都已經(jīng)幫我們做好了。
?????? 服務端的Module就是這些了,接下來就是客戶端的實現(xiàn)。
????????? 下面是客戶端整體結構:

?????? 注意,aidl文件可以直接從服務端copy過來,整個文件夾一起copy,確保packageName一致,不然是實現(xiàn)不了IPC通信的。然后build一下,系統(tǒng)就會幫我們生成aidl對應的java文件。下面是MainActivity具體的實現(xiàn):


?????? 因為服務端已經(jīng)實現(xiàn)了回調監(jiān)聽,所以客戶端不需要去關心什么時候會到新書什么時候獲取新書,只需要注冊監(jiān)聽即可,注冊監(jiān)聽我們放在ServiceConnection的onServiceConnected方法中,然后在金廷其中做相應處理即可。整個AIDL通信最基礎的實現(xiàn)就是這些了,可以更具項目具體的需求做相應的修改,我只是記錄一下自己的做法,有錯誤的地方還望指正。