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數據的話,就應該分開傳。理論上說,應該都是對象和字符串類型的數據為主,只要不是大圖片實體等問題,一般應該夠用。

我是天王蓋地虎的分割線


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM