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 } };