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



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

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;
	}

	@Override
	public int hashCode() {
		// TODO Auto-generated method stub
		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 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必须要实现的方法
	@Override
	public int describeContents() {
		return 0;
	}

	@Override
	public void writeToParcel(Parcel dest, int flags) {
		// 把该对象所包含的数据写到Parcel
		dest.writeInt(id);
		dest.writeString(name);
		dest.writeString(pass);
	}

	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) {
			// TODO Auto-generated method stub
			return 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;
	}

	@Override
	public int describeContents() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public String toString() {
		return "Pet [name=" + name + ", weight=" + weight + "]";
	}

	@Override
	public 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>() {

		@Override
		public Pet createFromParcel(Parcel source) {
			// 从Parcel中读取数据,返回Pet对象
			return new Pet(source.readString(), source.readDouble());

		}

		@Override
		public 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);

	}

	@Override
	public void onCreate() {
		super.onCreate();
		petBinder = new PetBinder();
	}

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return petBinder;
	}

	// 继承Stub,也就是实现了IPet接口,并实现了IBinder接口
	public class PetBinder extends Stub {

		@Override
		public List<Pet> getPets(Person owner) throws RemoteException {
			// TODO Auto-generated method stub
			return pets.get(owner);
		}

	}

	@Override
	public 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;

	@Override
	protected 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");

		// 绑定远程Service
		bindService(intent, conn, Service.BIND_AUTO_CREATE);
		get.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {

				try {
					String personName = personView.getText().toString();
					// 调用远程Service的方法
					List<Pet> pets = petService.getPets(new Person(1,
							personName, personName));
					// 将程序返回的List包装成ArrayAdapterpter
					ArrayAdapter<Pet> adapter = new ArrayAdapter<>(
							ComplexClient.this,
							android.R.layout.simple_list_item_1, pets);

					showView.setAdapter(adapter);

				} catch (RemoteException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});

	}
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		this.unbindService(conn);
	}

	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) {
			// TODO Auto-generated method stub
			petService = null;
		}

	};

}
时间: 2024-08-04 17:06:09

Android---45---使用AIDL Service传递复杂数据的相关文章

android 怎样用AIDL Service 传递复杂数据

大家都知道在Android中通过AIDL可以跨进程调用Service中的数据,网上也有很多实例,但是大部分实例都是关于基本数据类型的远程调用,很少讲到复杂数据的调用,今天我用一个例子来演示一下怎样用AIDL Service 传递复杂数据. 我们分2步开始: 第一步:部署我们的服务端,也就是Service端: 1:在Service端我先自定义2个类型:Person和Pet.因为我们需要跨进程传递Person对象和Pet对象,所以Person类和Pet类都必须实现Parcelable接口,并要求在实

怎样用AIDL Service 传递复杂数据

大家都知道在Android中通过AIDL可以跨进程调用Service中的数据,网上也有很多实例,但是大部分实例都是关于基本数据类型的远程调用,很少讲到复杂数据的调用,今天我用一个例子来演示一下怎样用AIDL Service 传递复杂数据. 我们分2步开始: 第一步:部署我们的服务端,也就是Service端: 1:在Service端我先自定义2个类型:Person和Pet.因为我们需要跨进程传递Person对象和Pet对象,所以Person类和Pet类都必须实现Parcelable接口,并要求在实

Android中activity之间如何传递Hashmap数据

我的使用场景是当一个页面需页面中的listview中的hashmap的数据时要另一个,就要用到了传递hashmap数据. 在发送方,我的代码是这样的: package cn.oddcloud.www.coffeestore.Test; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View;

android 多进程 Binder AIDL Service

本文参考http://blog.csdn.net/saintswordsman/article/details/5130947 android的多进程是通过Binder来实现的,一个类,继承了Binder,那么它的对象就可以被远程的进程使用了(前提是远程进程获取了这个类的对象[对象的引用],至于如如何获得看下文),怎么使用呢?在Android中, 则采用AIDL(Android InterfaceDefinition Language:接口定义语言)方式实现,所以我们必须写后缀为.aidl的文件

[Android]HttpPost之post请求传递Json数据

懒得打字 /** * 发送post请求传递Json */ public void jieXi() { new Thread(new Runnable() { public void run() { // Json中的引号必须加 \ 转义 String getLightJson = "{\"object\":\"light\",\"action\":\"get\"}"; String jsonParent =

Android学习笔记二十六.跨进程调用Service(AIDL Service)

跨进程调用Service(AIDL Service) 一.AIDL Service 1.什么是AIDL Service? AIDL,即Android Interface Definition Language.是Android用于定义远程接口,AIDL接口定义语言的语法比较简单,这种接口定义语言并不是真正的编程语言,它只是定义两个进程之间的通信接口.AIDL的语法与Java接口很相似,但存在如下几点差异: (1)AIDL定义接口的源代码必须以.aidl结尾; (2)AIDL接口中用到数据类型,除

Android中的跨进程通信方法实例及特点分析(一):AIDL Service

转载请注明出处:http://blog.csdn.net/bettarwang/article/details/40947481 最近有一个需求就是往程序中加入大数据的采集点,但是因为我们的Android程序包含两个进程,所以涉及到跨进程通信的问题.现将Android中的跨进程通信方式总结如下. Android中有4种跨进程通信方式,分别是利用AIDL Service.ContentProvider.Broadcast.Activity实现. 1.利用AIDL Service实现跨进程通信 这是

Abdroid---44---使用AIDL Service 实现跨进程调用Service

 为了实现跨进程通信(interprocess communication 简称 IPC),Android提供了AIDL Service. AIDL 是一种IDL语言,用于生成可以在Android设备上两个进程之间进行通信的代码 如果在一个进程中药调用另一个进程中对象的操作,就可以使用AIDL生成可序列化的参数. AIDL是面向接口的 与绑定本地Service不同的是,本地Service的onBind方法会直接把IBinder对象本身传给客户端的ServiceConnection 的onSe

Android AIDL Service 跨进程传递复杂数据

黑夜 黑夜给了我黑色的眼睛,我却用它寻找光明~ 传值方式 AIDL是同意跨进程传递值的,一般来说有三种方式: - 广播:这样的算是比較常见的一种方式了,传递小数据不错 - 文件:这个是保存到文件里.然后读取,传递大数据不错 - Service Bind模式.这个算是居中的一种方式,只是效率要高的多,唯一麻烦的是编写代码较为麻烦. 特别是复杂类型数据传递麻烦. 其是,另一些其它的办法进行数据传递.另外传递也并非仅仅能够使用一种,能够採用几种结合的方式进行. 今天要说的就是Service Bind进