Android---45---使用AIDL Service传递复杂数据

来源:互联网 发布:mindjet mac 编辑:程序博客网 时间:2024/04/29 04:07


该实例所传输的数据类型是自定义类型。


Android 要求调用远程Service的参数和返回值都需要实现Parcelable接口。


实现Parcelable接口相当于Android提供的一种自定义序列化机制。


实现Parcelable接口不仅要求实现该接口里定义的方法,而且要求在实现类中定义一个名为CREATOR
类型为Parcelable.Creator的静态Filed。除此之外,还要求使用AIDL代码来定义这些自定义类型。



服务端:

自定义两个类型:Person与Pet,其中Person对象作为调用远程Service的参数,而Pet将作为返回值。

Person 和 Pet类都必须实现 Parcelable接口,并在实现类中定义一个名为CREATOR的静态Filed。


要定义Person类,先要AIDL来定义Person类:


parcelable Person;

接下来定义Person实现Parcelable的类


public class Person implements Parcelable {private Integer id;private String name;private String pass;public Person() {super();// TODO Auto-generated constructor stub}public Person(Integer idInteger, String name, String pass) {super();this.id = idInteger;this.name = name;this.pass = pass;}public Integer getIdInteger() {return id;}public void setIdInteger(Integer idInteger) {this.id = idInteger;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPass() {return pass;}public void setPass(String pass) {this.pass = pass;}@Overridepublic int hashCode() {// TODO Auto-generated method stubfinal int prime = 31;int result = 1;result = prime * result + ((name == null) ? 0 : name.hashCode());result = prime * result + ((pass == null) ? 0 : pass.hashCode());return result;}@Overridepublic boolean equals(Object o) {if (this == o) {return true;}if (o == null) {return false;}if (getClass() != o.getClass()) {return false;}Person other = (Person) o;if (name == null) {if (other.name != null) {return false;}} else if (!name.equals(other.name)) {return false;}if (pass == null) {if (other.pass != null) {return false;}} else if (!pass.equals(other.pass)) {return false;}return true;}// 实现Parcelable必须要实现的方法@Overridepublic int describeContents() {return 0;}@Overridepublic void writeToParcel(Parcel dest, int flags) {// 把该对象所包含的数据写到Parceldest.writeInt(id);dest.writeString(name);dest.writeString(pass);}public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {@Overridepublic Person createFromParcel(Parcel source) {// 从Parcel中读取数据,返回Person对象return new Person(source.readInt(), source.readString(),source.readString());}@Overridepublic Person[] newArray(int size) {// TODO Auto-generated method stubreturn new Person[size];}};}


然后是Pet类,也是先定义AIDL中的Pet:

parcelable Pet; 



然后是定义Pet类实现Parcelable:


public class Pet implements Parcelable {private String name;private double weight;public Pet(String name, double weight) {super();this.name = name;this.weight = weight;}public Pet() {super();// TODO Auto-generated constructor stub}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getWeight() {return weight;}public void setWeight(double weight) {this.weight = weight;}@Overridepublic int describeContents() {// TODO Auto-generated method stubreturn 0;}@Overridepublic String toString() {return "Pet [name=" + name + ", weight=" + weight + "]";}@Overridepublic void writeToParcel(Parcel dest, int flags) {dest.writeString(name);dest.writeDouble(weight);}// 添加一个静态成员,名为CREATOR,该对象实现了Parcelable.Creator接口public static final Parcelable.Creator<Pet> CREATOR = new Parcelable.Creator<Pet>() {@Overridepublic Pet createFromParcel(Parcel source) {// 从Parcel中读取数据,返回Pet对象return new Pet(source.readString(), source.readDouble());}@Overridepublic Pet[] newArray(int size) {return new Pet[size];}};}


有了Person和Pet自定义的类,接下来就要定义用于通信的接口了:IPet


还是先是AIDL中定义:


package com.example.complexaidlservice;import com.example.complexaidlservice.Pet;import com.example.complexaidlservice.Person;//定义一个Person对象作为传入对象interface IPet{List<Pet> getPets (in Person owner );}


接下来就是开发Service类了:


public class ComplexService extends Service {private PetBinder petBinder;private static Map<Person, List<Pet>> pets = new HashMap<Person, List<Pet>>();static {ArrayList<Pet> list1 = new ArrayList<Pet>();list1.add(new Pet("旺财", 4.3));list1.add(new Pet("来福", 5.4));pets.put(new Person(1, "sun", "sun"), list1);ArrayList<Pet> list2 = new ArrayList<Pet>();list2.add(new Pet("Kitty", 2.3));list2.add(new Pet("garfiled", 3.1));pets.put(new Person(2, "bai", "bai"), list2);}@Overridepublic void onCreate() {super.onCreate();petBinder = new PetBinder();}@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubreturn petBinder;}// 继承Stub,也就是实现了IPet接口,并实现了IBinder接口public class PetBinder extends Stub {@Overridepublic List<Pet> getPets(Person owner) throws RemoteException {// TODO Auto-generated method stubreturn pets.get(owner);}}@Overridepublic void onDestroy() {}}




接下来该写客户端的代码了:

还记得在上一篇中写到的,需要把服务端的AIDL接口复制过来,传递复杂数据的时候,不仅仅只将IPet复制过来
同时也要将 Person.java,Person.aidl Pet.aidl,Pet.java 一起复制到客户端。

还是按照之前绑定远程Service的方式即可,并在ServiceConnection实现类的onServiceConnected方法中
获取远程Service的onBind方法返回的代理对象即可。



public class ComplexClient extends Activity {private IPet petService;private Button get;EditText personView;ListView showView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);personView = (EditText) findViewById(R.id.person);showView = (ListView) findViewById(R.id.show);get = (Button) findViewById(R.id.get);Intent intent = new Intent();intent.setAction("com.example.complexaidlservice.COMPLEXSERVICE");// 绑定远程ServicebindService(intent, conn, Service.BIND_AUTO_CREATE);get.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {try {String personName = personView.getText().toString();// 调用远程Service的方法List<Pet> pets = petService.getPets(new Person(1,personName, personName));// 将程序返回的List包装成ArrayAdapterpterArrayAdapter<Pet> adapter = new ArrayAdapter<>(ComplexClient.this,android.R.layout.simple_list_item_1, pets);showView.setAdapter(adapter);} catch (RemoteException e) {// TODO Auto-generated catch blocke.printStackTrace();}}});}@Overrideprotected void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();this.unbindService(conn);}private ServiceConnection conn = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {// 获取远程Service的onBind方法返回的对象的代理petService = IPet.Stub.asInterface(service);}@Overridepublic void onServiceDisconnected(ComponentName name) {// TODO Auto-generated method stubpetService = null;}};}










0 0