Android 使用AIDL实现进程之间的通信(一)

下面开始介绍下Android 之间进程之间的通信方式,AIDL是Android之间进程通信的方式之一,底层依然使用的是Binder,随后会介绍Binder的实现原理

创建AIDL文件

在AndroidStudio 中创建AIDL文件,会自动创建AIDL目录,在工程中与Java目录平级

// IMyAidl.aidl
package cn.edu.hebust.aidldemo;

// Declare any non-default types here with import statements

interface IMyAidl {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     * AIDL 通信的基本数据类型
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);

    // 提供给其他客户端的接口方法
    int add(int num1, int num2);
}

ctrl+b 进行编译,或者是用SDKtool提供的工具,将AIDL文件编译成.java文件
生成的java文件在
~/app/build/generated/source/aidl/debug/cn/edu/hebust/aidldemo

这个文件不需要我们更改,但是理解以后对我们了解Binder还是很有帮助的

/*
 * This file is auto-generated.  DO NOT MODIFY.
 * Original file: /media/yangtianrui/system/AndroidProject/AndroidStudioProjects/AIDLDemo/app/src/main/aidl/cn/edu/hebust/aidldemo/IMyAidl.aidl
 */
package cn.edu.hebust.aidldemo;
// Declare any non-default types here with import statements

public interface IMyAidl extends android.os.IInterface {
    /**
     * Local-side IPC implementation stub class.
     */
    public static abstract class Stub extends android.os.Binder implements cn.edu.hebust.aidldemo.IMyAidl {
        private static final java.lang.String DESCRIPTOR = "cn.edu.hebust.aidldemo.IMyAidl";

        /**
         * Construct the stub at attach it to the interface.
         */
        public Stub() {
            this.attachInterface(this, DESCRIPTOR);
        }

        /**
         * Cast an IBinder object into an cn.edu.hebust.aidldemo.IMyAidl interface,
         * generating a proxy if needed.
         */
        public static cn.edu.hebust.aidldemo.IMyAidl asInterface(android.os.IBinder obj) {
            if ((obj == null)) {
                return null;
            }
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
            if (((iin != null) && (iin instanceof cn.edu.hebust.aidldemo.IMyAidl))) {
                return ((cn.edu.hebust.aidldemo.IMyAidl) iin);
            }
            return new cn.edu.hebust.aidldemo.IMyAidl.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_basicTypes: {
                    data.enforceInterface(DESCRIPTOR);
                    int _arg0;
                    _arg0 = data.readInt();
                    long _arg1;
                    _arg1 = data.readLong();
                    boolean _arg2;
                    _arg2 = (0 != data.readInt());
                    float _arg3;
                    _arg3 = data.readFloat();
                    double _arg4;
                    _arg4 = data.readDouble();
                    java.lang.String _arg5;
                    _arg5 = data.readString();
                    this.basicTypes(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);
                    reply.writeNoException();
                    return true;
                }
                case TRANSACTION_add: {
                    data.enforceInterface(DESCRIPTOR);
                    int _arg0;
                    _arg0 = data.readInt();
                    int _arg1;
                    _arg1 = data.readInt();
                    int _result = this.add(_arg0, _arg1);
                    reply.writeNoException();
                    reply.writeInt(_result);
                    return true;
                }
            }
            return super.onTransact(code, data, reply, flags);
        }

        private static class Proxy implements cn.edu.hebust.aidldemo.IMyAidl {
            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;
            }

            /**
             * Demonstrates some basic types that you can use as parameters
             * and return values in AIDL.
             * AIDL 通信的基本数据类型
             */
            @Override
            public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) 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.writeInt(anInt);
                    _data.writeLong(aLong);
                    _data.writeInt(((aBoolean) ? (1) : (0)));
                    _data.writeFloat(aFloat);
                    _data.writeDouble(aDouble);
                    _data.writeString(aString);
                    mRemote.transact(Stub.TRANSACTION_basicTypes, _data, _reply, 0);
                    _reply.readException();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
            }

            @Override
            public int add(int num1, int num2) throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                int _result;
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    _data.writeInt(num1);
                    _data.writeInt(num2);
                    mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);
                    _reply.readException();
                    _result = _reply.readInt();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
                return _result;
            }
        }

        static final int TRANSACTION_basicTypes = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
        static final int TRANSACTION_add = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
    }

    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     * AIDL 通信的基本数据类型
     */
    public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException;

    public int add(int num1, int num2) throws android.os.RemoteException;
}

提供对外开放的Service

public class MyServer extends Service {

    // 这里是对提供的Java AIDL文件的实现
    // 通过onBind方法对外通信
    private IMyAidl.Stub mStub = new IMyAidl.Stub() {
        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

        }

        // 我们需要调用的方法
        @Override
        public int add(int num1, int num2) throws RemoteException {
            return num1 + num2;
        }
    };

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

这个Service的声明如下,我们需要这个Service对外开放,并且使用单独的进程运行

<!--process 带有':'属性表示这个组件的进程是私有的,只要有有互端去启动,系统就会创建一个新的进程去运行-->
<!--不带表示这个进程时共享的&ndash;&gt;-->
<service
    android:name=".MyServer"
    android:exported="true"
    android:process=":remote">
    <intent-filter>
        <action android:name="cn.hebust.myservice" />
    </intent-filter>
</service>

客户端的AIDL

这里客户端要拿到服务端的AIDL目录,并且实现对应的Java文件

// 直接在MainActivity中进行进行bindService
public class MainActivity extends AppCompatActivity {

    private IMyAidl mStub;
    // 使用一个Connection实现相互通信
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mStub = IMyAidl.Stub.asInterface(service);
            try {
                // 调用aidl interface的方法
                int value = mStub.add(5, 5);
                Toast.makeText(MainActivity.this, value + "", Toast.LENGTH_SHORT).show();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 启动服务端程序
        Intent intent = new Intent();
        intent.setAction("cn.hebust.myservice");
        ComponentName componentName = new ComponentName("cn.edu.hebust.aidldemo"
                , "cn.edu.hebust.aidldemo.MyServer");
        intent.setComponent(componentName);
        bindService(intent, conn, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        unbindService(conn);
        super.onDestroy();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值