您的位置:首页 > 移动开发 > Android开发

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

2017-06-17 11:40 363 查看

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.p
9a57
rintStackTrace();
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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android