Android 中的AIDL

Android中, 每个应用程序都可以有自己的进程. 在写UI应用的时候, 经常要用到Service. 在不同的进程中, 怎样传递对象呢?

如果必须进行跨进程之间的数据传递,那么我们就应该使用AIDL(Android Interface Definition Language)。

直接看代码:

服务端:

定义一个*.aidl文件,该文件里是符合aidl语言规范的接口定义,里面定义了外部应用可以访问的方法。当我们保存该文件的时候,eclipse会自动为我们在gen文件夹下生成一个相应的java接口文件。这里实现的服务端只做了一些数据封装,供客户端来调用.

工程图如下:


IPet.aidl

package org.crazyit.service;

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

//定义parcelable的person类

Person.aidl

parcelable Person; 

//定义parcelable的Pet类

 

Pet.aidl

<pre name="code" class="java"><span style="font-size:18px;">parcelable Pet; </span>
 
aidl携带对象型数据时,类要实现parcelable
Person.java
package org.crazyit.service;
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];
		}
	};
}
Pet.java
 
package org.crazyit.service;
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) {
		super();
		this.name = name;
		this.weight = weight;
	}

	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() {
		return 0;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.os.Parcelable#writeToParcel(android.os.Parcel, int)
	 */
	@Override
	public void writeToParcel(Parcel dest, int flags) {
		// 把该对象所包含的数据写到Parcel
		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中读取数据,返回Person对象
			return new Pet(source.readString(), source.readDouble());
		}

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

	@Override
	public String toString() {
		return "Pet [name=" + name + ", weight=" + weight + "]";
	}
}
Service:(实现数据封装)
 
package org.crazyit.service;

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

import org.crazyit.service.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);

		ArrayList<Pet> list3 = new ArrayList<Pet>();
		list3.add(new Pet("kitty", 2.3));
		list3.add(new Pet("garfield", 3.1));
		pets.put(new Person(3, "java", "java"), list3);
	}

	// 继承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注册服务,定义</span></span>
<intent-filter>
             <action android:name="org.crazyit.aidl.action.COMPLEX_SERVICE" />
            </intent-filter>
<span style="font-family: Arial, Helvetica, sans-serif;">这个action要与客户端的一致。</span>

客户端:

直接把服务端的整个包拷贝过来,除了ComplexService不需要。
工程图如下:

<pre name="code" class="java">package org.crazyit.client;

import java.util.List;
import org.crazyit.service.IPet;
import org.crazyit.service.Person;
import org.crazyit.service.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("org.crazyit.aidl.action.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);
	}
}


 程序最后运行效果: 
OK! 搞定!
</pre><span style="font-family: SimSun; color: rgb(54, 46, 43);"><span style="font-size:18px; line-height:26px"><br /><br /><br /></span></span><pre>
</pre><pre>



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值