传递复杂数据的AIDL Service
该实例所传输的数据类型是自定义类型。
1.ComplexService
1.定义调用Service 的参数对应的类 Person类
Person.aidl
parcelable Pet;
Person.java
调用远程Service的参数和返回值都必须实现Parcelable接口
(后面将在HashMap中使用该自定义类作为键值来存储 所以需要重写相关方法(hashCode() equals()))
package com.example.complexservice;
import android.os.Parcel;
import android.os.Parcelable;
public class Person implements Parcelable{
private int id;
private String name;
private String pass;
public Person(){
}
public Person(int id,String name,String pass){
this.id = id;
this.name = name;
this.pass = pass;
}
public String getName(){
return this.name;
}
@Override
public int hashCode()
{
return 1;
}
@Override
public boolean equals(Object obj)
{
if(this == obj)
return true;
//if(!(obj instanceof(Person)))
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if(this.name.equals(other.name))
return true;
else
return false;
}
//must implemented method
@Override
public int describeContents() {
return 0;
}
@Override
//write the data of the Person object to the parcel(Parcel dest)
public void writeToParcel(Parcel dest, int flags){
dest.writeInt(this.id);
dest.writeString(this.name);
dest.writeString(this.pass);
}
//end for must implemented method
public static final Parcelable.Creator<Person> CREATOR
= new Parcelable.Creator<Person>() {
@Override
//read data from the parcel(Parcel in) to create Person Object
public Person createFromParcel(Parcel in) {
return new Person(in.readInt(),in.readString(),in.readString());
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
}
2.定义调用Service的返回值 对应的类Pet
parcelable Pet;
package com.example.complexservice;
import android.os.Parcel;
import android.os.Parcelable;
public class Pet implements Parcelable{
private String name;
private double weight;
public Pet(){
}
public Pet(String name, double weight){
this.name = name;
this.weight = weight;
}
@Override
public String toString()
{
return "Pet [name=" + name + ", weight=" + weight + "]";
}
//must implemented method
@Override
public int describeContents() {
return 0;
}
@Override
//write the data of the Pet object to the parcel(Parcel dest)
public void writeToParcel(Parcel dest, int flags){
dest.writeString(this.name);
dest.writeDouble(this.weight);
}
//end for must implemented method
public static final Parcelable.Creator<Pet> CREATOR
= new Parcelable.Creator<Pet>() {
@Override
//read data from the parcel(Parcel in) to create Pet Object
public Pet createFromParcel(Parcel in) {
return new Pet(in.readString(),in.readDouble());
}
@Override
public Pet[] newArray(int size) {
return new Pet[size];
}
};
}
3.使用AIDL定义通信接口
IPet.aidlpackage com.example.complexservice;
import com.example.complexservice.Person;
import com.example.complexservice.Pet;
interface IPet{
//define my own interface method
// use Person object as the *in parameter*
// use List<Pet> as the returned parameter
List<Pet> getPets(in Person owner);
}
4.开发Service类 并配置该Service
ComplexService.java
package com.example.complexservice;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import com.example.complexservice.IPet.Stub;
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("dog1",22));
list1.add(new Pet("cat1",22.3));
Person p1 = new Person(1,"zhangshan","zhangshan");
pets.put(p1, list1);
ArrayList<Pet> list2 = new ArrayList<Pet>();
list2.add(new Pet("dog2",17));
list2.add(new Pet("cat2",5.3));
Person p2 = new Person(2,"xiaoli","xiaoli");
pets.put(p2, list2);
}
public class PetBinder extends Stub{
@Override
// List<Pet> getPets(in Person owner) throws RemoteException{
//overwrite the method in the interface(the method we can call from this service)
public List<Pet> getPets(Person owner) throws RemoteException{// no "in" here
return pets.get(owner);
/* for(Map.Entry<Person, List<Pet>> e : pets.entrySet()){
if(e.getKey().getName().equals(owner.getName())){
Log.i("main", "find info");
return e.getValue();
}
}
return null;*/
}
}
@Override
public IBinder onBind(Intent intent) {
return petBinder;
}
@Override
public void onCreate(){
super.onCreate();
petBinder = new PetBinder();//create the service object
}
@Override
public void onDestroy(){
super.onDestroy();
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.complexservice"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<service
android:name="com.example.complexservice.ComplexService"
>
<intent-filter>
<action android:name="android.intent.action.ComplexService"/>
</intent-filter>
</service>
</application>
</manifest>
2.complexclient
(1)开发客户端的第一步不仅需要把IPet.aid文件复制过去 ,还要把定义Person类和Pet类的AIDL文件和Java文件都复制过去。
需要注意的是:
在工程中定义服务端和客户端交互的接口,跟服务端的一模一样,包名也要一样,不然会报错
java.lang.SecurityException: Binder invocation to an incorrect interface
(2)ComplexClient.java
package com.example.complexclient;
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.view.Menu;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
//
import com.example.complexservice.IPet;
import com.example.complexservice.IPet.Stub;
import com.example.complexservice.Person;
import com.example.complexservice.Pet;
//
public class ComplexClient extends Activity {
//
private IPet petService;//remote service interface
//ui component
private Button get;
private EditText person;
private EditText person_id;
private ListView show;
private ServiceConnection conn = new ServiceConnection(){
@Override
public void onServiceConnected(ComponentName name, IBinder service){
//获取远程Service 的 onBind()方法返回的对象代理
petService = Stub.asInterface(service);//
}
@Override
public void onServiceDisconnected(ComponentName name){
petService = null;
}
};
//
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_complex_client);
//
get = (Button)findViewById(R.id.get);
person = (EditText)findViewById(R.id.person);
person_id = (EditText)findViewById(R.id.person_id);
show = (ListView)findViewById(R.id.show);
Intent intent = new Intent();
intent.setAction("android.intent.action.ComplexService");
bindService(intent, conn, Service.BIND_AUTO_CREATE);
get.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
try{
// TODO Auto-generated method stub
// int id = Integer.getInteger(ComplexClient.this.person_id.getText().toString());
//int id = Integer.getInteger("1");//wrong 返回类型为Integer 不是int
int id = Integer.parseInt(ComplexClient.this.person_id.getText().toString());
String person_name = ComplexClient.this.person.getText().toString();
//call the method of remote service
List<Pet> pets = new ArrayList<Pet>();
pets = ComplexClient.this.petService.getPets(new Person(id,
person_name,person_name));
ArrayAdapter<Pet> adapter = new ArrayAdapter<Pet>(ComplexClient.this,
android.R.layout.simple_list_item_1,pets);//Pet toString()
ComplexClient.this.show.setAdapter(adapter);
}catch(RemoteException e){
Toast.makeText(ComplexClient.this, "fail to call remote service",
Toast.LENGTH_LONG).show();
}catch(Exception e){
e.printStackTrace();
Toast.makeText(ComplexClient.this, "other exception",
Toast.LENGTH_LONG).show();
}
}
});
//
}
@Override
public void onDestroy(){
super.onDestroy();
this.unbindService(conn);//unbind the service when this activity exited
}
}