Aidl实现进程间通信,跨进程回调

aidl支持的文件类型

1. Java 编程语言中的基本类型, 如 int、long、boolean 等, 不需要 import.

2. String、List、Map 和 CharSequence, 不需要 import.

3. AIDL 生成的 interface, 需要 import, 同一个包中也需要导入, 传递的是引用.
  如果定义的接口方法中有参数, 则需在前面加上 in, out 或 inout, 但是对于基本类型的参数, 默认就是 in, 并且不会是其他值.

4. Parcelable 接口的自定义类, 需要 import, 同一个包中也需要导入, 其传递的是值.

另外, 自定义类还需要用一个aidl文件来声明该类型.
如定义了一个类, 它的源代码在RoadLine.java中:
  package com.communicate;
  import android.os.Parcel;
  import android.os.Parcelable;
  public class RoadLine implements Parcelable {
需要在RoadLine.aidl文件中做如下声明:
  package com.communicate;
  import com.communicate.RoadLine;
  parcelable RoadLine;


AIDL 实现回调

1. 建立2个aidl文件,  一个用于声明回调的接口,  另一个用于定义注册接口, 及服务端调用的通知方法. 如:

package com.apical.contact;

import com.apical.contact.RoadLine;
import com.apical.contact.CarData;

interface IDVRRoadMetaDataCallback {
    void onMetaData(int cameraId, in List<RoadLine> roadLines, in List<CarData> carDatas);
}
package com.apical.contact;

import com.apical.contact.IDVRRoadMetaDataCallback;
import com.apical.contact.RoadLine;
import com.apical.contact.CarData;

interface IDVRRoadMetaDataTaskBinder {
    void registerCallback(int cameraId, IDVRRoadMetaDataCallback callback);

    void unregisterCallback(int cameraId, IDVRRoadMetaDataCallback callback);

    void onUpdateMetaData(int cameraId, in List<RoadLine> roadLines, in List<CarData> carDatas);
}

 

2. 实现服务端后台Service类. 要实现回调, 需要使用RemoteCallbackList对象, 一个存储回调对象的列表

private RemoteCallbackList<IDVRRoadMetaDataCallback> mCallbackList = new RemoteCallbackList<>();
注册
mCallbackList.register(callback);
取消注册
mCallbackList.unregister(callback);
方法调用
int count = mCallbackList.beginBroadcast();
try {
for (int i = 0; i < count; i++) {
mCallbackList.getBroadcastItem(i).onMetaData(cameraId, roadLines, carDatas);
}
} catch (RemoteException e) {
Dlog.e("E/onUpdateMetaDatas", e);
} finally {
mCallbackList.finishBroadcast();
}

package com.communicate;

import java.util.List;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Log;

public class DvrMetaDataService extends Service {

    private static final String TAG = "debug";
    
    private RemoteCallbackList<IDVRRoadMetaDataCallback> mCallbackList = new RemoteCallbackList<>();

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

    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    public IDVRRoadMetaDataTaskBinder.Stub mBinder = new IDVRRoadMetaDataTaskBinder.Stub() {

        @Override
        public void registerCallback(int cameraId, IDVRRoadMetaDataCallback callback) throws RemoteException {
            mCallbackList.register(callback);
        }

        @Override
        public void unregisterCallback(int cameraId, IDVRRoadMetaDataCallback callback) throws RemoteException {
            mCallbackList.unregister(callback);
        }

        @Override
        public void onUpdateMetaData(int cameraId, List<RoadLine> roadLines, List<CarData> carDatas) throws RemoteException {
            int count = mCallbackList.beginBroadcast();
            try {
                for (int i = 0; i < count; i++) {
                    mCallbackList.getBroadcastItem(i).onMetaData(cameraId, roadLines, carDatas);
                }
            } catch (RemoteException e) {
                Log.e(TAG, "E/onUpdateMetaDatas", e);
            } finally {
                mCallbackList.finishBroadcast();
            }
        }
    };
}

  注册服务,必须指定exported为true

        <service android:name="com.communicate.DvrMetaDataService" android:exported="true">
        </service>

 

3. 服务端绑定服务, 调用数据通知方法.

    Intent metaDataService = new Intent();
    metaDataService.setComponent(new ComponentName(com.communicate, com.communicate.DvrMetaDataService));
    boolean result = bindService(metaDataService, mMetaDataConn, Service.BIND_AUTO_CREATE);
    
    /** DVR Meta data 共享数据服务 */
    private IDVRRoadMetaDataTaskBinder mMetaDataServiceTaskBinder;
    private ServiceConnection mMetaDataConn = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
        }

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            mMetaDataServiceTaskBinder = IDVRRoadMetaDataTaskBinder.Stub.asInterface(iBinder);
        }
    };

    在更新数据时调用
        if (mMetaDataServiceTaskBinder != null) {
            try {
                mMetaDataServiceTaskBinder.onUpdateMetaData(cameraId, roadLines, carDatas);
            } catch (RemoteException e) {
                Dlog.e("E/OnCameraMetaDataChange", e);
            }
        }

 

4. 客户端绑定服务, 注册接口, 实现回调的功能.需要注意的是, 由于服务端也绑定了服务,或者多个客户端同时绑定服务, unbindService时并不会调用 onServiceDisconnected 方法, 因此客户端不需要使用时要适时取消注册.

    Intent metaDataService = new Intent();
    metaDataService.setComponent(new ComponentName(MetaDataServiceConfig.META_DATA_SERVICE_PKG_NAME,
            MetaDataServiceConfig.META_DATA_SERVICE_CLASS_NAME));
    boolean result = bindService(metaDataService, mServiceConnection, Service.BIND_AUTO_CREATE);
    Log.d(TAG, "result = " + result);
    
    private ServiceConnection mServiceConnection = new ServiceConnection() {

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            try {
                if (mIDVRRoadMetaDataTaskBinder != null) {
                    mIDVRRoadMetaDataTaskBinder.unregisterCallback(0, mCallback);
                    mIDVRRoadMetaDataTaskBinder = null;
                }
            } catch (RemoteException e) {
                Log.e(TAG, "", e);
            }
        }

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            Log.d(TAG, "(DvrMetaDataService - onServiceConnected");
            mIDVRRoadMetaDataTaskBinder = IDVRRoadMetaDataTaskBinder.Stub.asInterface(iBinder);
            try {
                mIDVRRoadMetaDataTaskBinder.registerCallback(0, mCallback);
            } catch (RemoteException e) {
                Log.e(TAG, "", e);
            }
        }
    };
    
    private IDVRRoadMetaDataTaskBinder mIDVRRoadMetaDataTaskBinder;

    private IDVRRoadMetaDataCallback mCallback = new IDVRRoadMetaDataCallback.Stub() {
        @Override
        public void onMetaData(int cameraId, List<RoadLine> roadLines, List<CarData> carDatas) throws RemoteException {
            Log.d(TAG, "-> onMetaData :" + carDatas);
            // do something needed
        }
    };

 

posted @ 2016-06-14 11:45  阿Hai  阅读(1308)  评论(0)    收藏  举报