時隔一年半了,終於寫下了這個續篇,我發現我的很多博客有頭無尾,都是有前面一點點,後面就沒寫去了,也正在想辦法都補上
初涉IPC,瞭解AIDL的工作原理及使用方法
今天聊聊的是客戶端和服務端的相互通信,何謂雙向通信,事實上,我們在上一篇的博客中,只是講解了客戶端請求服務端的方法,然後服務端返回一個值給我們這樣,其實是最簡單的用法,但是常常在我們的開發過程中,如果調用了某些方法,比如網絡請求,那麼就需要等待請求有結果了之後再回調給我們,這個回調的過程就是服務端向客戶端通信,作爲ipc通信的一種,如果你不會雙向通信,那麼你可以比較low的用廣播,但是我還是建議你直接用一整套的AIDL複用,好的,那麼問題來了,我們怎麼下手呢?
服務端
我們新建兩個工程,一個叫ADILClient,一個叫AIDLService,分別代表的是客戶端和服務端
我們現在開始編寫我們的aidl,這裏我需要編寫兩個AIDL文件,一個是我們對外的方法,一個是我們對外的回調方法,如圖
這裏我做一下講解,首先我new了一個aidl的文件夾,在main下,和java同級,然後定義了一個公共的包名:com.android.openimpl,最後在裏面實現了兩個aidl文件,我們來看下具體的文件內容
IMyLifeStyleInterface
// IMyLifeStyleInterface.aidl
package com.android.openimpl;
import com.android.openimpl.IMyLifeStyleListener;
interface IMyLifeStyleInterface {
//計算
void sum(int a ,int b);
//睡覺
void sleep(boolean isSleep);
//註冊
void registerCallback(IMyLifeStyleListener il);
//解綁
void unregisterCallback(IMyLifeStyleListener il);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
IMyLifeStyleListener
// IMyLifeStyleListener.aidl
package com.android.openimpl;
//回調接口
interface IMyLifeStyleListener {
//回調方法
void OnCallBackSleep(String text);
void OnCallBackSize(int size);
}
1
2
3
4
5
6
7
8
9
10
11
這裏我定義了IMyLifeStyleInterface ,裏面有兩個方法,假設我定義的事一個人,他有基本的兩個本能,一個是計算,我傳兩個數字給他,他進行一系列的處理,那麼,問題來, 我不想用返回值,我想通過回調知道,這是一點,另一個是睡覺,而在IMyLifeStyleListener,我也定義了兩個對應的回調OnCallBackSleep和OnCallBackSize,好了,現在開始來實現我們的遠程Service服務
public class OpenImplService extends Service {
private IMyLifeStyleListener lifeStyleListener;
private IBinder mBinder = new IMyLifeStyleInterface.Stub() {
@Override
public void sum(int a, int b) throws RemoteException {
//經過一系列的計算後將值告知客戶端
int c = a * 2 + b;
if (lifeStyleListener != null) {
lifeStyleListener.OnCallBackSize(c);
}
}
@Override
public void sleep(boolean isSleep) throws RemoteException {
//告訴客戶端我已經睡着
if(isSleep){
if (lifeStyleListener != null) {
lifeStyleListener.OnCallBackSleep("幫我關下燈,謝謝!");
}
}
}
@Override
public void registerCallback(IMyLifeStyleListener il) throws RemoteException {
if (il != null) {
lifeStyleListener = il;
}
}
@Override
public void unregisterCallback(IMyLifeStyleListener il) throws RemoteException {
if (il != null) {
lifeStyleListener = null;
}
}
};
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
這裏,我定義了一個遠程的服務OpenImplService,裏面我只是new了IMyLifeStyleInterface.Stub並且把Binder對象給了onBind方法,而在Binder內部,我做的操作相信大家都看的明白吧,很簡單,Ok,那我們的服務端就已經搞定了,我們來看下服務端的整體結構
當然,別忘了在清單文件中註冊
<service
android:name=".service.OpenImplService"
android:enabled="true"
android:exported="true" />
1
2
3
4
客戶端
好的,現在就開始來實現我們的客戶端,客戶端也需要同樣的AIDL文件,所以我可以直接複製過去,但是要注意的是包名一定要相同,如圖
這裏,我的客戶端就是app包下的東西,那麼我們來實現UI上的邏輯