zoukankan      html  css  js  c++  java
  • 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
            }
        };
  • 相关阅读:
    .NET设计模式系列文章[转]
    asp.net MVC+NHibernate项目开发日志
    NHibernate 中关于 unsavedvalue 的问题
    领域驱动设计DDD之读书笔记
    让人郁闷的“DesktopCompatible”
    实战DDD(DomainDriven Design)领域驱动设计
    手机软件开发中的P/Invoke
    如何配置NHibernate的XML配置文件的智能感知(IntelliSense)功能 ?
    转]WinCE中的未公开函数
    Nhibernate+MVC开发日志
  • 原文地址:https://www.cnblogs.com/diysoul/p/5583540.html
Copyright © 2011-2022 走看看