AIDL in out inout 的区别


学而不思则罔,思而不学则殆

在定义AIDL的时候需要设置in out 或者 inout,开始的时候不清楚其中的区别,于是自己写了一个Demo来测试验证一下,看了很多文章,也只有自己亲自懂事试一试才能更加深刻,完整的记录下我分析的过程和源码,同大家一同分享。

Demo

https://github.com/aJanefish/BinderInOutStudy

结论

字段数据流动说明
in客服端到服务端服务端将会接收到一个那个对象的完整数据,但是客户端的那个对象不会因为服务端对传参的修改而发生变动
out服务端到客户端服务端将会接收到那个对象的的空对象(默认对象),但是在服务端对接收到的空对象有任何修改之后客户端将会同步变动
inout双向的服务端将会接收到客户端传来对象的完整信息,并且客户端将会同步服务端对该对象的任何变动

代码

// IBinderTestService.aidl
package com.zy.ipc;

import com.zy.ipc.AidlBean;

interface IBinderTestService {
   void InTest(in AidlBean bean);
   void InTestShow();
   void OutTest(out AidlBean bean);
   void OutTestShow();
   void InOutTest(inout AidlBean bean);
   void InOutTestShow();
}
public class AidlBean implements Parcelable {
    int id;
    String name;

    public AidlBean() {
        this(0, "DEFAULT"); //默认
    }

    public AidlBean(int id, String name) {
        this.id = id;
        this.name = name;
    }
    ...
}

in测试

服务端如下,打印客户端传过来的参数,保留下来,更改参数:

        @Override
        public void InTest(AidlBean bean) throws RemoteException {
            Log.d(TAG, "InTest start:" + bean);
            in = bean;
            bean.setId(1);
            bean.setName("Service InTest");
            Log.d(TAG, "InTest end:" + bean);
        }

        @Override
        public void InTestShow() throws RemoteException {
            Log.d(TAG, "InTestShow start:" + in);
            in.setName("Service InTest Show");
            Log.d(TAG, "InTestShow end:" + in);
        }

客户端实现:
打印传入参数的前后结果,观察变化:

    AidlBean inBean = new AidlBean(1000, "client inTest");
    public void inTest(View view) {
        try {
            Log.d(TAG, "inTest start:" + inBean);
            iBinderTestService.InTest(inBean);
            Log.d(TAG, "inTest end:" + inBean);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    public void inTestShow(View view) {
        try {
            //修改传入的参数
            inBean.setName("client inTest Show");
            Log.d(TAG, "inTestShow start:" + inBean);
            iBinderTestService.InTestShow();
            Log.d(TAG, "inTestShow end:" + inBean);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

测试inTest

结果:

08-02 06:58:29.110  4345  4345 D zhangyu.MainActivity: inTest start:AidlBean{id=1000, name='client inTest Show'}hashCode:44098254
08-02 06:58:29.111  4263  4290 D zhangyu.InOutService: InTest start:AidlBean{id=1000, name='client inTest Show'}hashCode:264932469
08-02 06:58:29.111  4263  4290 D zhangyu.InOutService: InTest end:AidlBean{id=1, name='Service InTest'}hashCode:264932469
08-02 06:58:29.111  4345  4345 D zhangyu.MainActivity: inTest end:AidlBean{id=1000, name='client inTest Show'}hashCode:44098254

in标识,客户端的参数能够传递到服务端;
hashCode不一样,标识这是两个不同的对象,说明经过Binder传输过后,已经是不同的两个对象;
服务端修改传入的参数过后,客户端的并没有被修改,结论验证成立

测试inTestShow

该方法只是修改开始的inBean对象中的数据,然后分别打印调用服务端的方法前后的结果,结果如下:

08-02 07:02:52.194  4345  4345 D zhangyu.MainActivity: inTestShow start:AidlBean{id=1000, name='client inTest Show'}hashCode:44098254
08-02 07:02:52.194  4263  4290 D zhangyu.InOutService: InTestShow start:AidlBean{id=1, name='Service InTest'}hashCode:264932469
08-02 07:02:52.195  4263  4290 D zhangyu.InOutService: InTestShow end:AidlBean{id=1, name='Service InTest Show'}hashCode:264932469
08-02 07:02:52.196  4345  4345 D zhangyu.MainActivity: inTestShow end:AidlBean{id=1000, name='client inTest Show'}hashCode:44098254

这种情况下客户端的修改不能同步到服务端
同理服务端的修改也不能同步到客户端

out测试

服务端实现:

        @Override
        public void OutTest(AidlBean bean) throws RemoteException {
            Log.d(TAG, "OutTest start:" + bean);
            out = bean;
            bean.setId(2);
            bean.setName("Service OutTest");
            Log.d(TAG, "OutTest end:" + bean);
        }

        @Override
        public void OutTestShow() throws RemoteException {
            Log.d(TAG, "OutTestShow start:" + out);
            out.setName("Service OutTest Show");
            Log.d(TAG, "OutTestShow end:" + out);
        }

客户端实现:

    AidlBean outBean = new AidlBean(1000, "client outTest");
    public void outTest(View view) {
        try {
            Log.d(TAG, "outTest start:" + outBean);
            iBinderTestService.OutTest(outBean);
            Log.d(TAG, "outTest end:" + outBean);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    public void outTestShow(View view) {
        try {
            //修改传入的参数
            outBean.setName("client outTest Show");
            Log.d(TAG, "outTestShow start:" + outBean);
            iBinderTestService.OutTestShow();
            Log.d(TAG, "outTestShow end:" + outBean);

        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

测试OutTest

方法跟inTest一样,打印调用方法前后的对象,log如下:

08-02 07:09:15.109  4345  4345 D zhangyu.MainActivity: outTest start:AidlBean{id=2, name='client outTest Show'}hashCode:123397693
08-02 07:09:15.110  4263  4290 D zhangyu.InOutService: OutTest start:AidlBean{id=0, name='DEFAULT'}hashCode:126329866
08-02 07:09:15.110  4263  4290 D zhangyu.InOutService: OutTest end:AidlBean{id=2, name='Service OutTest'}hashCode:126329866
08-02 07:09:15.113  4345  4345 D zhangyu.MainActivity: outTest end:AidlBean{id=2, name='Service OutTest'}hashCode:123397693

现象和结论:

  1. hashCode不一样,客户端和服务端是不同的对象
  2. 服务端打印的是默认的Bean对象,说明客户端的参数没有传递到服务端,在接口用out修饰的情况下
  3. 服务端修改了Bean对象的值过后,客户端的值也被修改了,说明这种情况下,服务端的修改可以同步到客户端

测试OutTestShow

08-02 07:09:37.648  4345  4345 D zhangyu.MainActivity: outTestShow start:AidlBean{id=2, name='client outTest Show'}hashCode:123397693
08-02 07:09:37.649  4263  4290 D zhangyu.InOutService: OutTestShow start:AidlBean{id=2, name='Service OutTest'}hashCode:126329866
08-02 07:09:37.649  4263  4290 D zhangyu.InOutService: OutTestShow end:AidlBean{id=2, name='Service OutTest Show'}hashCode:126329866
08-02 07:09:37.650  4345  4345 D zhangyu.MainActivity: outTestShow end:AidlBean{id=2, name='client outTest Show'}hashCode:123397693

现象和结论:

客户端和服务端的修改各不相关,不会同步

inout测试

服务端实现:

        @Override
        public void InOutTest(AidlBean bean) throws RemoteException {
            Log.d(TAG, "InOutTest start:" + bean);
            inout = bean;
            bean.setId(3);
            bean.setName("Service InOutTest");
            Log.d(TAG, "InOutTest end:" + bean);
        }

        @Override
        public void InOutTestShow() throws RemoteException {
            Log.d(TAG, "OutTestShow start:" + inout);
            inout.setName("Service InOutTest show");
            Log.d(TAG, "OutTestShow end:" + inout);
        }

客户端实现:

    AidlBean inoutBean = new AidlBean(1000, "client inoutTest");
    public void inoutTest(View view) {
        try {
            Log.d(TAG, "inoutTest start:" + inoutBean);
            iBinderTestService.InOutTest(inoutBean);
            Log.d(TAG, "inoutTest end:" + inoutBean);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    public void inoutTestShow(View view) {
        try {
            //修改传入的参数
            inoutBean.setName("client inoutTest Show");
            Log.d(TAG, "inoutTestShow start:" + inoutBean);
            iBinderTestService.InOutTestShow();
            Log.d(TAG, "inoutTestShow end:" + inoutBean);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

测试InOutTest

log如下:

08-02 07:16:14.543  4345  4345 D zhangyu.MainActivity: inoutTest start:AidlBean{id=3, name='client inoutTest Show'}hashCode:12528664
08-02 07:16:14.545  4263  4290 D zhangyu.InOutService: InOutTest start:AidlBean{id=3, name='client inoutTest Show'}hashCode:41423995
08-02 07:16:14.545  4263  4290 D zhangyu.InOutService: InOutTest end:AidlBean{id=3, name='Service InOutTest'}hashCode:41423995
08-02 07:16:14.546  4345  4345 D zhangyu.MainActivity: inoutTest end:AidlBean{id=3, name='Service InOutTest'}hashCode:12528664

现象与结论:

  1. 不是同一对象
  2. 开始时打印的对象值相同。客户端对象可以传递到服务端
  3. 结束时打印的对象值相同。服务端对象可以传递到客户端

测试InOutTestShow

log如下:

08-02 07:16:18.197  4345  4345 D zhangyu.MainActivity: inoutTestShow start:AidlBean{id=3, name='client inoutTest Show'}hashCode:12528664
08-02 07:16:18.198  4263  4290 D zhangyu.InOutService: OutTestShow start:AidlBean{id=3, name='Service InOutTest'}hashCode:41423995
08-02 07:16:18.198  4263  4290 D zhangyu.InOutService: OutTestShow end:AidlBean{id=3, name='Service InOutTest show'}hashCode:41423995
08-02 07:16:18.199  4345  4345 D zhangyu.MainActivity: inoutTestShow end:AidlBean{id=3, name='client inoutTest Show'}hashCode:12528664

现象和结论:

客户端和服务端的修改各不相关,不会同步

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值