AIDL中的传参及in、out、inout

前言

今天开发AIDL,新建一个接口,写了一个函数,结果build的时候报错了

Process ‘command ‘xxx/aidl’’ finished with non-zero exit value 1

经过长时间的尝试终于搞定,期间也回顾了不少知识,一起总结一下。

AIDL默认支持的数据类型

来看看IData.aidl的源码:

package jun.server;

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

interface IBaseData {
    
    
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    // 不支持short类型
    void basicTypes(byte aByte, int anInt, long aLong,
            boolean aBoolean,
            float aFloat, double aDouble,
            char aChar,
            String aString, CharSequence aCharSequence,
            inout List<String> aList);
}

除short外的Java八大基本数据类型,String、CharSequence、以及List。当我们传入的参数不是这些类型时,就会报错。还有一些情况:

  • list的元素类型不能是基本类型,比如List<Long>List<Byte>
  • 缺少import会报错。aidl不会自动import,所以需要我们手动添加,添加时由于没有提示,一定要注意正确

in\out\inout

有些类型缺少in\out\inout标签,也会报错。比如:

  • list类型的参数,如List<String>
  • 基本类型的数组,如byte[]
  • Parcelable的实现类,如Bundle

那么这三个标签有什么作用?

  • in 表示数据只能由客户端流向服务端
  • out 表示数据只能由服务端流向客户端
  • inout 则表示数据可在服务端与客户端之间双向流通。

其中,数据流向是针对在客户端中的那个传入方法的对象而言的。

  • in 为定向 tag 的话表现为服务端将会接收到一个那个对象的完整数据,但是客户端的那个对象不会因为服务端对传参的修改而发生变动;
  • out 的话表现为服务端将会接收到那个对象的的空对象,但是在服务端对接收到的空对象有任何修改之后客户端将会同步变动;
  • inout 为定向 tag 的情况下,服务端将会接收到客户端传来对象的完整信息,并且客户端将会同步服务端对该对象的任何变动。

举例说一下:

如果将一个参数设为out,客户端调用该函数并传入了一个对象数据,但是服务端接受到的是一个空对象,但是服务端可以为这个对象赋值,赋值后客户端那边的对象也会跟着改变。

自定义类

自定义类后,在aidl需要添加对应文件,否则报错。

有时我们需要传递一些复杂数据,需要自定义一个类,这个类必须实现Parcelable。这个类必须在客户端和服务端都有一份。

然后我们在aidl的函数中使用这个类型的参数,但是依然报错,已经添加import也报错。

是因为我们需要在aidl中添加一个对应的文件

比如

package cn.xxx.xxx;
public class Product implements Parcelable {
    
    
    ...
}

在aidl接口中

package com.xxx.xxx;

//注意:这里有一个巨坑,这包名不能加aidl。不然会报错
import com.xxx.xxxx.Product;

interface IMyAidlInterface {
    
    
    void do(in String country, in Product product);
}

这里不仅添加了import,而且也为该类型添加了in标签,但是依然报错。

这就需要在aidl目录下添加一个对应的文件,如下

package com.xxx.xxxx;

parcelable Product;

注意包名要一样。

传参是回调

传参可以是一个回调,这个回调实际上也是一个aidl接口,比如

package cn.xxx.xxx;

import cn.xxx.xxx.Callback;
interface IMyInterface {
    
    
    void setCallback(Callback callback);
}

CallBack文件

package cn.xxx.xxx;

interface Callback {
    
    
    void onDone(inout byte[] data, int length, int width, int height, int code);
}

这个callback也是一个aidl,不能是普通的接口,所以他的传参也需要遵循上面的约束

关注公众号:BennuCTech,获取更多干货!

猜你喜欢

转载自blog.csdn.net/chzphoenix/article/details/122706077