AIDL进程间传递⾃定义类型参数
1、创建.aidl ⽂件
AIDL 语法简单,⽤来声明接⼝,其中的⽅法接收参数和返回值,但是参数和返回值的类型是有约束的,且有些类型是需要 import,另外⼀些则⽆需这样做。
AIDL ⽀持的数据类型划分为四类,第⼀类是 Java 编程语⾔中的基本类型,第⼆类包括 String、List、Map 和 CharSequence,第三类是其他 AIDL ⽣成的 interface,第四类是实现了 Parcelable protocol 的⾃定义类。
其中,除了第⼀类外,其他三类在使⽤时均需要特别⼩⼼。
使⽤第⼆类时,⾸先需要明⽩这些类不需要 import,是内嵌的。其次注意在使⽤ List 和 Map 此⼆者容器类时,需注意其元素必须得是AIDL ⽀持的数据类型,List 可⽀持泛型,但是 Map 不⽀持,同时另外⼀端负责接收的具体的类⾥则必须是 ArrayList 和 HashMap。
使⽤第三、四类时,需要留意它们都是需要 import 的,但是前者传递时,传递的是 reference,⽽后者则是 value。
在创建 .aidl ⽂件的过程中,应该注意⼀旦 method 有参数,则需注意在前⾯加上 in, out 或 inout,它们被称为 directional tag,但是对于基本类型的参数,默认就是 in,并且不会是其他值。
Aidl默认⽀持的类型包话java基本类型(int、long、boolean等)和(String、List、Map、CharSequence),如果要传递⾃定义的类型该如何实现呢?
要传递⾃定义类型,⾸先要让⾃定义类型⽀持parcelable协议,实现步骤如下:
1>⾃定义类型必须实现Parcelable接⼝,并且实现Parcelable接⼝的public void writeToParcel(Parcel dest, int flags)⽅法 。
2>⾃定义类型中必须含有⼀个名称为CREATOR的静态成员,该成员对象要求实现Parcelable.Creator接⼝及其⽅法。
3> 创建⼀个aidl⽂件声明你的⾃定义类型。
Parcelable接⼝的作⽤:实现了Parcelable接⼝的实例可以将⾃⾝的状态信息(状态信息通常指的是各成员变量的值)写⼊Parcel,也可以从Parcel中恢复其状态。 Parcel⽤来完成数据的序列化传递。
个人住房公积金查询1> 创建⾃定义类型,并实现Parcelable接⼝,使其⽀持parcelable协议。如:在cn.jp.domain包下创建Person.java:
import android.os.Parcel;
import android.os.Parcelable;
public class Person implements Parcelable
宣传营销private Integer id;
private String name;
public Person(){}
public Person(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void tId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void tName(String name) {
this.name = name;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {//把javanbean中的数据写到Parcel
dest.writeInt(this.id);
dest.writeString(this.name);
}
//添加⼀个静态成员,名为CREATOR,该对象实现了Parcelable.Creator接⼝
public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>(){
@Override
public Person createFromParcel(Parcel source) {//从Parcel中读取数据,返回person对象
return new adInt(), adString());
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
}
2> 在⾃定义类型所在包下创建⼀个aidl⽂件对⾃定义类型进⾏声明,⽂件的名称与⾃定义类型同名。
package cn.jp.domain;
parcelable Person;
3> 在接⼝aidl⽂件中使⽤⾃定义类型,需要使⽤import显式导⼊,本例在cn.jp.aidl包下创建IPersonService.aidl⽂件,内容如下:
import cn.itcast.domain.Person;
interface IPersonService {
void save(in Person person);
}
4> 在实现aidl⽂件⽣成的接⼝(本例是IPersonService),但并⾮直接实现接⼝,⽽是通过继承接⼝的Stub来实现(Stub抽象类内部实现了aidl接⼝),并且实现接⼝⽅法的代码。内容如下:
public class ServiceBinder extends IPersonService.Stub {
校园手抄报@Override
public void save(Person person) throws RemoteException {
Log.i("PersonService", Id()+"="+ Name());
}
}
5> 创建⼀个Service(服务),在服务的onBind(Intent intent)⽅法中返回实现了aidl接⼝的对象(本例是ServiceBinder)。内容如下:
public class PersonService extends Service {
private ServiceBinder rviceBinder = new ServiceBinder();
@Override
public IBinder onBind(Intent intent) {
return rviceBinder;
}
public class ServiceBinder extends IPersonService.Stub {
@Override
public void save(Person person) throws RemoteException {
Log.i("PersonService", Id()+"="+ Name());
}
}
}
按制度办事其他应⽤可以通过隐式意图访问服务,意图的动作可以⾃定义,l配置代码如下:
<rvice android:name=".PersonService" >
<intent-filter>
<action android:name="cn.jp.process.aidl.PersonService " />
</intent-filter>
</rvice>
6> 把应⽤中的aidl⽂件和所在package⼀起拷贝到客户端应⽤的src⽬录下,eclip会⾃动在客户端应⽤的gen⽬录中为aidl⽂件同步⽣ 成IPersonService.java接⼝⽂件,接下来再把⾃定义类型⽂件和类型声明aidl⽂件及所在package⼀起拷贝到客户端应⽤的src ⽬录下。
最后就可以在客户端应⽤中实现与远程服务的通信,代码如下:
public class ClientActivity extends Activity {
不忘初心英文private IPersonService personService;
@Override
public void onCreate(Bundle savedInstanceState) {
黑加仑葡萄干的功效与作用
tContentView(R.layout.main);
this.bindService(new Intent("cn.jp.process.aidl.PersonService"), this.rviceConnection, BIND_AUTO_CREATE);//绑定到服务}
@Override
protected void onDestroy() {
this.unbindService(rviceConnection);//解除服务
}
private ServiceConnection rviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder rvice) {
甜蜜爱情测试
personService = IPersonService.Stub.asInterface(rvice);
try {
6xxx
personService.save(new Person(56,"liming"));
} catch (RemoteException e) {
Log.e("ClientActivity", e.toString());
}