zoukankan      html  css  js  c++  java
  • Android Studio中实现AIDL

    AIDL

    先来两个传送门:
    http://www.cnblogs.com/yydcdut/p/3961545.html Android面试,与Service交互方式
    http://www.cnblogs.com/yydcdut/p/3810816.html Android -- Service绑定解绑和aidl

    Android Studio AIDL

    • 建立AIDL,通过点击建立AIDL文件:
    • 建立好之后就出现了AIDL文件:
    • Build-->Make Project,生成相应的java文件。

    • 先看看aidl文件

    // ICameraData.aidl
    package com.yydcdut.cameramvc;
    
    // Declare any non-default types here with import statements
    
    interface ICameraData {
        void add(String fileName,int size, long time);
    }
    

    生成的aidl文件:

    /*
     * This file is auto-generated.  DO NOT MODIFY.
     * Original file: /Users/yuyidong/AndroidStudioProjects/Camera-Camera2-MVC/app/src/main/aidl/com/yydcdut/cameramvc/ICameraData.aidl
     */
    package com.yydcdut.cameramvc;
    // Declare any non-default types here with import statements
    
    public interface ICameraData extends android.os.IInterface {
        /**
         * Local-side IPC implementation stub class.
         */
        public static abstract class Stub extends android.os.Binder implements com.yydcdut.cameramvc.ICameraData {
            private static final java.lang.String DESCRIPTOR = "com.yydcdut.cameramvc.ICameraData";
    
            /**
             * Construct the stub at attach it to the interface.
             */
            public Stub() {
                this.attachInterface(this, DESCRIPTOR);
            }
    
            /**
             * Cast an IBinder object into an com.yydcdut.cameramvc.ICameraData interface,
             * generating a proxy if needed.
             */
            public static com.yydcdut.cameramvc.ICameraData asInterface(android.os.IBinder obj) {
                if ((obj == null)) {
                    return null;
                }
                android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);//根据包名获取本地实现的一个接口的实例,如果是本地service则可以获取到
                if (((iin != null) && (iin instanceof com.yydcdut.cameramvc.ICameraData))) {
                    return ((com.yydcdut.cameramvc.ICameraData) iin);////如果得到的实例是ICameraData的对象,则返回
                }
                return new com.yydcdut.cameramvc.ICameraData.Stub.Proxy(obj);//如果无法得到本地实现的对象则会返回一个代理对象
            }
    
            @Override
            public android.os.IBinder asBinder() {
                return this;
            }
    
            @Override
            public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
                switch (code) {
                    case INTERFACE_TRANSACTION: {
                        reply.writeString(DESCRIPTOR);
                        return true;
                    }
                    case TRANSACTION_add: {
                        data.enforceInterface(DESCRIPTOR);
                        java.lang.String _arg0;
                        _arg0 = data.readString();//读取fileName
                        int _arg1;
                        _arg1 = data.readInt();//读取size
                        long _arg2;
                        _arg2 = data.readLong();//读取time
                        this.add(_arg0, _arg1, _arg2);
                        reply.writeNoException();
                        return true;
                    }
                }
                return super.onTransact(code, data, reply, flags);
            }
    
            private static class Proxy implements com.yydcdut.cameramvc.ICameraData {
                private android.os.IBinder mRemote;
    
                Proxy(android.os.IBinder remote) {
                    mRemote = remote;
                }
    
                @Override
                public android.os.IBinder asBinder() {
                    return mRemote;
                }
    
                public java.lang.String getInterfaceDescriptor() {
                    return DESCRIPTOR;
                }
    
                @Override
                public void add(java.lang.String fileName, int size, long time) throws android.os.RemoteException {
                    android.os.Parcel _data = android.os.Parcel.obtain();
                    android.os.Parcel _reply = android.os.Parcel.obtain();
                    try {
                        _data.writeInterfaceToken(DESCRIPTOR);
                        _data.writeString(fileName);//写入
                        _data.writeInt(size);//写入
                        _data.writeLong(time);//写入
                        mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);//调用binderDriver的提供的方法将参数发给服务端
                        _reply.readException();
                    } finally {
                        _reply.recycle();
                        _data.recycle();
                    }
                }
            }
    
            static final int TRANSACTION_add = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
        }
    
        public void add(java.lang.String fileName, int size, long time) throws android.os.RemoteException;
    }
    
    

    代理中也实现了ICameraData接口定义的方法,我们以add方法为例,里面将参数打包发送给Server端。在Server端收到请求后,会调用service中我们实现的那个stub对象(mBinder)的onTransact方法。

    如何在Studio中使用

    • 在Service中:
        ICameraData.Stub mStub = new ICameraData.Stub() {
            @Override
            public void add(String fileName, int size, long time) throws RemoteException {
                //.............
        };
          
        @Override
        public IBinder onBind(Intent intent) {
            return mStub;
        }
    
    • 在Activity中绑定Service:
    private ServiceConnection mServiceConnection = new ServiceConnection() {
    
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                mCameraService = ICameraData.Stub.asInterface(service);
                mIsBind = true;
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
                mCameraService = null;
                mIsBind = false;
            }
        };
    
    • 调用Service的方法:
    mCameraService.add(fileName, size, time);
    

    在Manifest中申明

    <service
                android:name=".CameraService"
                android:process=":remote"></service>
    

    注意

    android.os.TransactionTooLargeException

    在Android中,进程间通信通过binder实现,bind是通信的数据载体,当序列化后的数据单元过大时,就会出问题,报出android.os.TransactionTooLargeException。官方文档里有说明,最大通常限制为1M.也就是说如果大于1M数据的话,就应该分开传。理论上说,应该都是对象和字符串类型的数据为主,只要不是大图片实体等问题,一般应该够用。

    我是天王盖地虎的分割线

  • 相关阅读:
    物理材质
    铰链joints
    unity 刚体
    扩展方法
    转换操作符方法(非基元类型转换)
    向方法传递可变数量的参数
    参数:可选参数和命名参数
    实例构造器与值类型和引用类型、类型构造器
    成员的可访问性,友元程序集,静态类
    如何删除github上项目的文件
  • 原文地址:https://www.cnblogs.com/yydcdut/p/4770655.html
Copyright © 2011-2022 走看看