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

初学Android,传递复杂数据的Service(六十一)

2012-09-28 16:41 483 查看
本篇来学学怎么传递自定义数据类型,例中定义了两个类,Person和Pet,其中Person对象作为调用远程Service的参数,而Pet作为返回值.
不管是远程调用的参数,还是返回值都要求实现Parcelable接口.
实现Parcelable接口不仅要实现接口里定义方法,而且要在实现类中定义一个名为CREATOR,类型为Parcelable.Creator的静态Field.
除此之外还要求使用AIDL代码来定义这些自定义的类型
例如要定义Person类,先要定义AIDL定义Person类,创建一个名为Person.aidl的文件 

parcelable Person;
接着定义一个实现Parcelable接口的Person类

package WangLi.Service.ComplexService;

import android.os.Parcel;
import android.os.Parcelable;

public class Person implements Parcelable
{	
	private Integer id;
	private String name;
	private String pass;
	
	public Person()
	{
	}
	public Person(Integer id, String name, String pass)
	{
		super();
		this.id = id;
		this.name = name;
		this.pass = pass;
	}
	public Integer getId()
	{
		return id;
	}
	public void setId(Integer id)
	{
		this.id = id;
	}
	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;
	}
	@Override
	public int hashCode()
	{
		final int prime = 31;
		int result = 1;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + ((pass == null) ? 0 : pass.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 (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接口必须实现的方法
	@Override
	public int describeContents()
	{
		return 0;
	}
	// 实现Parcelable接口必须实现的方法
	@Override
	public void writeToParcel(Parcel dest, int flags)
	{
		//把该对象所包含的数据写到Parcel
		dest.writeInt(id);
		dest.writeString(name);
		dest.writeString(pass);		
	}

	// 添加一个静态成员,名为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.readInt()
				, source.readString()
				, source.readString());
		}

		@Override
		public Person[] newArray(int size)
		{
			return new Person[size];
		}
	};	
}

该类主要实现writeToParcel(Parcel dest,int flags)方法,访方法负责把Person对象的数据写入Parcel中
接着再定义一个Pet类,方式与Person类大致相同
有了这两个类以后,接下来就可以使用AIDL来定义通信接口了

package WangLi.Service.ComplexService;
import WangLi.Service.ComplexService.Pet;
import WangLi.Service.ComplexService.Person;

interface IPet
{
	// 定义一个Person对象作为传入参数
	List<Pet> getPets(in Person owner);
}

接下来开发一个Service类,让Service类的onBind方法返回IPet实现类的实例

package WangLi.Service.ComplexService;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import WangLi.Service.ComplexService.IPet.Stub;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;

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") , 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") , 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()
	{
	}	
}

在AndroidManifest.xml配置完上面的Service后,下面开发客户端来获取服务端的自定义数据

package WangLi.Service.ComplexClient;

import java.util.List;

import WangLi.Service.ComplexService.IPet;
import WangLi.Service.ComplexService.Person;
import WangLi.Service.ComplexService.Pet;
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.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;

public class ComplexClient extends Activity
{
	private IPet petService;
	private Button get;
	EditText personView;
	ListView showView;
	private ServiceConnection conn = new ServiceConnection()
	{
		@Override
		public void onServiceConnected(ComponentName name, IBinder service)
		{
			// 获取远程Service的onBind方法返回的对象的代理
			petService = IPet.Stub.asInterface(service);
		}

		@Override
		public void onServiceDisconnected(ComponentName name)
		{
			petService = 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);
		// 创建所需绑定服务的Intent
		Intent intent = new Intent();
		intent.setAction("WangLi.Service.Complex_Service");
		// 绑定远程服务
		bindService(intent, conn, Service.BIND_AUTO_CREATE);
		get.setOnClickListener(new OnClickListener()
		{
			@Override
			public void onClick(View arg0)
			{
				try
				{
					String personName = personView.getText().toString();
					// 调用远程Service的方法
					List<Pet> pets = petService.getPets(
						new Person(1, personName , personName));
					// 将程序返回的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(conn);
	}
}
运行效果如图



输入人名,返回他所拥有的宠物列表
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: