AIDL怎么使用自定义对象

这一部分资料很多,我一边看着艺术探索,一边看着博客也跟着来了一遍,但怎么都无法编译通过,各种各样的错误,找不到类,找不到字段,巴拉巴拉。我实在是很郁闷,这么一个小小的东西怎么搞了2个小时?!然后查了一串串资料后我终于成功了!看到编译通过那一刻我就决定写一篇文章把它记下来,再也不摔在这里!

1、创建对象并实现Parcelable,我们以Person类为例:
package com.example.servicetest;

import android.os.Parcel;
import android.os.Parcelable;

public class Person implements Parcelable {

    String name;

    int age;

    int sex;

    public Person(){

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getSex() {
        return sex;
    }

    public void setSex(int sex) {
        this.sex = sex;
    }


    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.name);
        dest.writeInt(this.age);
        dest.writeInt(this.sex);
    }

    //注意:这个方法需要手动实现,自动生成工具不会生成。且各字段读取顺序应该与writeToParcel一致
    public void readFromParcel(Parcel source) {
        name = source.readString();
        age = source.readInt();
        sex = source.readInt();
    }


    protected Person(Parcel in) {
        this.name = in.readString();
        this.age = in.readInt();
        this.sex = in.readInt();
    }

    public static final Creator<Person> CREATOR = new Creator<Person>() {
        @Override
        public Person createFromParcel(Parcel source) {
            return new Person(source);
        }

        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }
    };
}

Parcelable接口的方法实现可以使用AS自动生成,但不包括readFromParcel方法。readFromParcel需要我们手动实现,否则无法编译通过。另外,readFromParcel各字段的读取顺序需要与writeToParcel一致。

2、新建与自定义对象同名的aidl文件,Person.aidl

在这里需要做两件事,一是声明对象为parcelable类型,注意大小写;二是必须手动import Person类,哪怕它们在同一个包下:

// Person.aidl
package com.example.servicetest;

//必须手动import
import com.example.servicetest.Person;

//parcelable首字母小写
parcelable Person;

这里踩坑了,如果在Java目录下新建了Person.java类,再新建Person.aidl类会发现失败了,AS告诉你它们同名了:

image.png

解决办法是先新建aidl文件,再新建Java文件。
或者新建Java文件的时候把它创建在aidl目录下,像这样:等aidl文件也创建成功后,可以把Java文件再挪出去到Java目录下就没问题了,我晕...

image.png
3、在AIDL接口文件内同样import我们自定义的对象:

所有使用自定义对象的aidl文件都应该手动import它。

// PersonAIDL.aidl
package com.example.servicetest;

import com.example.servicetest.Person;

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

interface PersonAIDL {

    String getName();

    //in out inout只可用于非基础类型,
    void setNameIn(in Person name);
    void setNameOut(out Person name);
    void setNameInOut(inout Person name);
}

然后build一下,你会发现失败了,报错大致是,找不到这个自定义类。我已经疯了,查资料,没有问题,emmm...再查
然后!

4、最后一步,在build.gradle文件中添加如下代码

位置在android 标签内,这应该与aidl文件的结构相关,话说这么重要的一步操作那些高赞文章怎么都不说呢,非让人家掉进去一次,不过也记得格外清楚了,哎

    sourceSets {
        main {
            manifest.srcFile 'src/main/AndroidManifest.xml'
            java.srcDirs = ['src/main/java', 'src/main/aidl']
            resources.srcDirs = ['src/main/java', 'src/main/aidl']
            aidl.srcDirs = ['src/main/aidl']
            res.srcDirs = ['src/main/res']
            assets.srcDirs = ['src/main/assets']
        }
    }

踩了无数坑之后,终于编译通过了!一个小小的自定义对象居然这么艰辛!所以学东西一定要动手,眼睛是看不出这么多坑的,而且要记录,不然还会掉进去,到时候再一波一波的搜索解决方案可是有点费事儿了。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容