Android笔记三:Android 接口定义语言 (AIDL)--传递对象

Android 接口定义语言 (AIDL)–传递对象

通过 IPC 传递对象

通过 IPC 接口把某个类从一个进程发送到另一个进程是可以实现的。 不过,您必须确保该类的代码对 IPC 通道的另一端可用,并且该类必须支持 Parcelable 接口(也可支持java的Serializable序列化接口)。支持 Parcelable 接口很重要,因为 Android 系统可通过它将对象分解成可编组到各进程的原语。

如需创建支持 Parcelable 协议的类

您必须执行以下操作:

  • 1.让您的类实现 Parcelable 接口。

  • 2.实现 writeToParcel,它会获取对象的当前状态并将其写入 Parcel。

  • 3.为您的类添加一个名为 CREATOR 的静态字段,这个字段是一个实现 Parcelable.Creator 接口的对象。

//Person.java
public class Person implements Parcelable {

    private String name;
    private int age;

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

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

    public String getName() {

        return name;
    }

    public int getAge() {
        return age;
    }

    protected Person(Parcel in) {
        //读的顺序必须和写的顺序一致
        this.name = in.readString();
        this.age = in.readInt();
    }

    public Person(String name, int age) {
        //读的顺序必须和写的顺序一致
        this.name = name;
        this.age = age;
    }

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

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

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

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

    @Override
    public String toString() {
        return "[name:" + name + "age:" + age + "]";
    }
}
  • 4.最后,创建一个声明可打包类的 .aidl 文件(按照下文 Rect.aidl 文件所示步骤)。
// Person21.aidl
package com.example.admin.aidlservice;

//声明Person
parcelable Person;

如图:
这里写图片描述

给出IRemoteService.aidl代码

//IRemoteService.aidl
package com.example.admin.aidlservice;

//就算在同一个包下也需要导包
import com.example.admin.aidlservice.Person;

interface IRemoteService {
    //不是基本类型的参数需要表明方向(in/out...)
    List<Person> add(in Person person);
}

调用 IPC 方法

调用类必须执行以下步骤,才能调用使用 AIDL 定义的远程接口:

  • 1.在项目 src/ 目录中加入 .aidl 文件。
    这里写图片描述
  • 2.声明一个 IBinder 接口实例(基于 AIDL 生成)。
  • 3.实现 ServiceConnection。
  • 4.调用 Context.bindService(),以传入您的 ServiceConnection 实现。
  • 5.在您的 onServiceConnected() 实现中,您将收到一个 IBinder 实例(名为 service)。调用 IRemoteService.Stub.asInterface((IBinder)service),以将返回的参数转换为 YourInterface 类型。
  • 6.调用您在接口上定义的方法。您应该始终捕获 DeadObjectException 异常,它们是在连接中断时引发的;这将是远程方法引发的唯一异常。
  • 7.如需断开连接,请使用您的接口实例调用 Context.unbindService()。
//MainActivity
public class MainActivity extends AppCompatActivity {

    private static final String TAG = "lynnlee36";
    private ArrayList<Person> persons;
    private IRemoteService iRemoteService;

    private ServiceConnection conn = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            iRemoteService = IRemoteService.Stub.asInterface(service);
            addPerson();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            iRemoteService = null;
        }
    };

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

    public void addPerson(View view) {
        addPerson();
    }

    private void addPerson() {
        try {
            persons = (ArrayList<Person>) iRemoteService.add(new Person("lucy", 23));
            Log.i(TAG, "调用远程服务,结果是:" + persons.toString());
        } catch (RemoteException e) {
            e.printStackTrace();
            Log.i(TAG, "执行失败!");
        }
    }

    private void bindService() {
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.example.admin.aidlservice", "com.example.admin.aidlservice.RemoteService"));
        bindService(intent, conn, Context.BIND_AUTO_CREATE);
    }
}

猜你喜欢

转载自blog.csdn.net/lynnlee_36/article/details/73369525