Android進程間通信(IPC)之AIDL

前言

AIDL(Android Interface definition language)即Android接口定義語言。

項目實例

首先,準備兩個應用,一個作爲客戶端,一個作爲服務端。當然你也可以用一個應用實現,無非就是應用內跨進程和多應用跨進程的區別,原理是一樣的。下面分別對每個端上需要操作的步驟進行說明。

服務端:

第一步:創建aidl接口定義文件

在你的服務端項目中,右鍵->New->AIDL->AIDL File,輸入接口名稱,然後as會自動在/src/main目錄下生成aidl文件夾,路徑與主項目/src/main/java目錄一致。

這裏我創建了一個IUserProxy.aidl文件,並自定義瞭如下幾個接口

// IUserProxy.aidl
package com.xuhj.ipc.server;

// Declare any non-default types here with import statements
import com.xuhj.ipc.server.model.User;

interface IUserProxy {

    List<User> getUserList();

    void addUser(in User user);

}

如果用到自定義對象,比如我這裏用到了一個User對象,則必須實現Parcelable接口,同時需要在aidl目錄下新建一個aidl文件,進行該對象的聲明。
PS: 這個User對象建議最好也放在aidl目錄下,這樣方便後面把aidl中的文件全部複製到客戶端上來複用。

例如:這裏我創建了一個User對象,則需要再創建一個User.aidl文件,並添加如下聲明內容。
注意:這個User.aidl不要用自動生成aidl的方法去創建,需要自己手動新建New File,文件名爲User.aidl

package com.xuhj.ipc.server.model;

parcelable User;

以上步驟完成後,對項目進行一次Build,會在/build/generated/source/aidl下生成對應的java文件,這就是我們剛纔定義的IUserProxy.aidl轉換後的java類,有興趣可以查看相關資料。as只是幫我們自動完成了這個步驟,我們也可以完全自己寫這個java類。

第二步:創建Service服務類

新建類AidlService並繼承Service


public class AidlService extends Service {
    private static final String TAG = "服務端:AidlService";

    private Binder mBinder = new IUserProxy.Stub() {

        @Override
        public List<User> getUserList() throws RemoteException {
            Log.d(TAG, "收到客戶端的調用getUserList");
            return null;
        }

        @Override
        public void addUser(User user) throws RemoteException {
            Log.d(TAG, "收到客戶端的調用addUser");
        }

    };

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

}

最後別忘了在manifest中添加service聲明。這裏我用了action供其他應用調用。


        <service android:name=".service.AidlService">
            <intent-filter>
                <action android:name="com.xuhj.action.ipc.server.AidlService" />
            </intent-filter>
        </service>

好啦,一個簡單的服務端就這樣創建完成了。

客戶端:

第一步:複製aidl文件

把服務端的aidl文件全部複製到客戶端相同目錄下。這樣保證客戶端調用的和服務端調用的是一樣的類。

第二步:創建ServiceConnection服務連接類

新建類AidlConn並繼承ServiceConnection


public class AidlConn implements ServiceConnection {
    private static final String TAG = "客戶端:AidlConn";

    private com.xuhj.ipc.server.IUserProxy mIUserProxy;

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        mIUserProxy = com.xuhj.ipc.server.IUserProxy.Stub.asInterface(service);
        try {
            User sendUser = new User(77, "i am client");
            Log.d(TAG, "調用addUser");
            mIUserProxy.addUser(sendUser);

            Log.d(TAG, "調用getUserList");
            List<User> userList = mIUserProxy.getUserList();

        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
    }

}

第三步:開啓遠程服務

在客戶端的Activity中,開啓遠程服務


    private void invokeIPCAidlFromServer() {
        Intent i = new Intent();
        i.setAction("com.xuhj.action.ipc.server.AidlService");
        i.setPackage("com.xuhaj.ipc.server");
        AidlConn aidlConn = new AidlConn();
        bindService(i, aidlConn, BIND_AUTO_CREATE);
    }

好了,一個簡單的AIDL通信就這樣完成了。

如果需要多個AIDL通信,可以通過BinderPool來管理,有興趣可以查看相關資料。

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