这篇文章接着上一篇的AIDL实现跨进程通讯而来,说一下Android的序列化机制。
Parcelable接口相当于Android提供的一种自定义序列化机制,和Java本来就有的实现Serializable的序列化机制相比属于轻量级的。
在使用AIDL传递复杂对象时,我们必须保证要传递的对象经过了序列化,我们要传递一个Person对象,先要AIDL来定义Person类,这很简单:
package com.flyingduck.servicedemo3;
parcelable Person;
接下来就需呀定义一个实现了Parcelable接口的Person类:
package com.flyingduck.servicedemo3;
import android.os.Parcel;
import android.os.Parcelable;
public class Person implements Parcelable {
private String name;
private int ID;
public Person(String name, int iD) {
super();
this.name = name;
ID = iD;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getID() {
return ID;
}
public void setID(int iD) {
ID = iD;
}
//实现Parcelable接口必须实现的方法
@Override
public int describeContents() {
return 0;
}
//把对象的数据写到Parcel中
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(ID);
}
//添加一个静态成员,名为CREATOR,该对象实现了Parcelable.Creator接口
public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {
//从parcela中读取数据
@Override
public Person createFromParcel(Parcel source) {
return new Person(source.readString(), source.readInt());
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
}
实现Parcelable接口不仅需要实现接口中的方法,而且需要定义一个名为 CREATOR,类型是Parcelable.Creator的静态字段。实现Parcelable接口主要实现writeToParcel()方法,该方法负责把Person对象的数据写入Parcel中,同时我们定义的静态变量CREATOR负责从Parcel中恢复Person对象。
下面我们的例子稍微改动了上一篇的代码下:
aidl:
package com.flyingduck.servicedemo3;
import com.flyingduck.servicedemo3.Person;
interface ICommunication{
String getServiceInfo();
Person getPerson();
}
service:
package com.flyingduck.servicedemo3;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
public class AIDLService extends Service {
private ICommunication.Stub comm = new ICommunication.Stub() {
@Override
public String getServiceInfo() throws RemoteException {
return "I'm from AIDLService";
}
@Override
public Person getPerson() throws RemoteException {
return new Person("Duck",123);
}
};
@Override
public IBinder onBind(Intent arg0) {
return comm;
}
}
activity:
package com.flyingduck.servicedemo3;
import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class ClientActivity extends Activity {
private Button bindBtn;
private Button unbindBtn;
private TextView showTxt;
private ServiceConnection conn;
private ICommunication communication;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_client);
bindBtn = (Button) findViewById(R.id.bind_service);
unbindBtn = (Button) findViewById(R.id.un_bind_service);
showTxt = (TextView) findViewById(R.id.show);
conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
communication = ICommunication.Stub.asInterface(service);
try {
showTxt.setText(communication.getServiceInfo() + communication.getPerson().getName());
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
bindBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
bindService(new Intent(getApplicationContext(), AIDLService.class), conn, Service.BIND_AUTO_CREATE );
}
});
unbindBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
unbindService(conn);
}
});
}
}
运行后发现我们在Activity客户端取到了Service传递过来的Person对象,并将Person的name显示在屏幕上。