AIDL 客戶端與服務端的雙向通信

時隔一年半了,終於寫下了這個續篇,我發現我的很多博客有頭無尾,都是有前面一點點,後面就沒寫去了,也正在想辦法都補上

初涉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上的邏輯

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章