Android要求调用远程Service的参数和返回值都必须实现Parceable接口。实现Parceable接口不仅要求实现该接口里定义的方法,而且要求在实现类中定义一个名为CREATOR、类型为Parcelable.Creator的静态Field。除此之外,还要求使用AIDL代码来定义这些自定义类型。
// Service 1.1 Person.aidl
parcelable Person;
// Service 1.2
public class Person implements Parcelable {
private Integer mId;
private String mName;
private String mPass;
public boolean mOwned;
private Bundle mBundle;
public Person() {
}
public Person(Integer id, String name, String pass, boolean owned, Bundle bundle) {
super();
this.mId = id;
this.mName = name;
this.mPass = pass;
this.mOwned = owned;
if (bundle != null) {
mBundle = bundle;
} else {
mBundle = new Bundle();
}
}
public Person(Person person) {
this.mId = person.mId;
this.mName = person.mName;
this.mPass = person.mPass;
this.mOwned = person.mOwned;
this.mBundle = person.mBundle;
}
public Person(Parcel in) {
this.mId = in.readInt();
this.mName = in.readString();
this.mPass = in.readString();
this.mOwned = in.readInt() != 0 ? true : false;
this.mBundle = in.readBundle();
}
public Integer getId() {
return mId;
}
public void setId(Integer id) {
this.mId = id;
}
public String getName() {
return mName;
}
public void setName(String name) {
this.mName = name;
}
public String getPass() {
return mPass;
}
public void setPass(String pass) {
this.mPass = pass;
}
// 实现Parcelable接口必须实现的方法
@Override
public int describeContents() {
return 0;
}
// 实现Parcelable接口必须实现的方法
@Override
public void writeToParcel(Parcel dest, int flags) {
// 把该对象所包含的数据写到Parcel
dest.writeInt(mId);
dest.writeString(mName);
dest.writeString(mPass);
dest.writeInt(mOwned ? 1 : 0);
dest.writeBundle(mBundle);
}
// 添加一个静态成员,名为CREATOR,该对象实现了Parcelable.Creator接口
public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {
@Override
public Person createFromParcel(Parcel source) {
// 从Parcel中读取数据,返回Person对象
return new Person(source);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((mName == null) ? 0 : mName.hashCode());
result = prime * result + ((mPass == null) ? 0 : mPass.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (mName == null) {
if (other.mName != null)
return false;
} else if (!mName.equals(other.mName))
return false;
if (mPass == null) {
if (other.mPass != null)
return false;
} else if (!mPass.equals(other.mPass))
return false;
return true;
}
}
// Service 2
package org.crazyit.service;
import org.crazyit.service.Pet;
import org.crazyit.service.Person;
interface IPet {
// 定义一个Person对象作为传入参数
List<Pet> getPets(in Person owner);
}
// Service 3
public class ComplexService extends Service {
private PetBinder petBinder;
private static Map<Person, List<Pet>> pets = new HashMap<Person, List<Pet>>();
static {
// 初始化pets Map集合
ArrayList<Pet> list1 = new ArrayList<Pet>();
list1.add(new Pet("旺财", 4.3));
list1.add(new Pet("来福", 5.1));
pets.put(new Person(1, "sun", "sun", false, null), list1);
ArrayList<Pet> list2 = new ArrayList<Pet>();
list2.add(new Pet("kitty", 2.3));
list2.add(new Pet("garfield", 3.1));
pets.put(new Person(2, "bai", "bai", false, null), list2);
}
// 继承Stub,也就是实现额IPet接口,并实现了IBinder接口
public class PetBinder extends Stub {
@Override
public List<Pet> getPets(Person owner) throws RemoteException {
// 返回Service内部的数据
return pets.get(owner);
}
}
@Override
public void onCreate() {
super.onCreate();
petBinder = new PetBinder();
}
@Override
public IBinder onBind(Intent arg0) {
/*
* 返回catBinder对象 在绑定本地Service的情况下,该catBinder对象会直接
* 传给客户端的ServiceConnection对象 的onServiceConnected方法的第二个参数;
*
* 在绑定远程Service的情况下,只将catBinder对象的代理 传给客户端的ServiceConnection对象
* 的onServiceConnected方法的第二个参数;
*/
return petBinder;
}
@Override
public void onDestroy() {
}
}
// 4
<service android:name=".ComplexService" >
<intent-filter>
<action android:name="org.crazyit.aidl.action.COMPLEX_SERVICE" />
</intent-filter>
</service>
// Client 1
public class ComplexClient extends Activity {
private IPet mPetService;
private Button get;
EditText personView;
ListView showView;
private final ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 获取远程Service的onBind方法返回的对象的代理
mPetService = IPet.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
mPetService = null;
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
personView = (EditText) findViewById(R.id.person);
showView = (ListView) findViewById(R.id.show);
get = (Button) findViewById(R.id.get);
// 创建所需绑定的Service的Intent
Intent intent = new Intent();
intent.setAction("org.crazyit.aidl.action.COMPLEX_SERVICE");
// 绑定远程Service
bindService(intent, mConnection, Service.BIND_AUTO_CREATE);
get.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
try {
String personName = personView.getText().toString();
// 调用远程Service的方法
List<Pet> pets = mPetService.getPets(new Person(1, personName, personName, false, null)); // ①
// 将程序返回的List包装成ArrayAdapter
ArrayAdapter<Pet> adapter = new ArrayAdapter<Pet>(ComplexClient.this, android.R.layout.simple_list_item_1, pets);
showView.setAdapter(adapter);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
@Override
public void onDestroy() {
super.onDestroy();
// 解除绑定
this.unbindService(mConnection);
}
}