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

Android 进程间通信(IPC)---AIDL入门

2016-03-07 17:08 441 查看
AIDL简介

  AIDL是 Android Interface Definition Language的缩写。AIDL 是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行 IPC的代码。如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。

这里我们需要建立两个工程,一个作为客户端,另外一个作为服务端。

一、建立客户端的工程,结构如下:



首先新建一个package(com.zjt.myaidl)。在该package中新建一个名为IMyService.aidl的文件。如下:

package com.zjt.myaidl;
import com.zjt.myaidl.Person;
interface IMyService{
List<Person> getPerson();
void addPerson(in Person person);
}


说明:

AIDL支持java基本类型如: int, long,double, char, boolean等。其他类型必须要用import 导入,即使是在同一个包中。比如本工程中IMyService和Person是在同一个包中。

另外,接口中的参数除了aidl支持的类型,其他类型必须标识其方向:到底是输入还是输出抑或两者兼之,用in,out或者inout来表示,上面的代码我们用in标记,因为它是输入型参数。

如果需要访问自定义对象,还需要建立对象的aidl文件,这里我们由于使用了自定义对象Person,所以还需建立一个Person.aidl文件。

由于使用了自定义对象Person,那么需要对该对象进行序列化。这里我们让Person 类实现Parcelable接口。

Person.java:

public class Person implements Parcelable {

private String name ;
private int age;
private String sex;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getSex() {
return sex;
}

public void setSex(String sex) {
this.sex = sex;
}

public Person(String name,int age , String sex){
this.name = name;
this.age = age;
this.sex = sex;
}

public Person(){

}

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

@Override
public void writeToParcel(Parcel dest, int flags) {
// TODO Auto-generated method stub
Log.e("xxx", "writeToParcel");
//这里字段写的顺序要和下面读的顺序要一致,从name、age到sex
dest.writeString(name);
dest.writeInt(age);
dest.writeString(sex);
}

public static final Parcelable.Creator<Person> CREATOR = new Creator<Person>() {

@Override
public Person[] newArray(int size) {
// TODO Auto-generated method stub
return new Person[size];
}

@Override
public Person createFromParcel(Parcel source) {
// TODO Auto-generated method stub
Person person = new Person();
//这里字段读的顺序要和下面写的顺序要一致,从name、age到sex
person.name = source.readString();
person.age = source.readInt();
person.sex = source.readString();
return person;
}
};

}


Person.aidl文件很简单,如下所示,要注意的是 这里parcelable是个类型,首字母是小写的,和Parcelable接口不是一个东西。

package com.zjt.myaidl;
parcelable Person;


二、建立服务端的Service,MyService.java文件如下:

public class MyService extends Service{

//private IBinder mBinder;

private List<Person> mPersons = new ArrayList<Person>();

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

@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Person mPerson = new Person("zjt", 28, "male");
mPersons.add(mPerson);
}
//在这里实现aidl中的抽象方法
private final IMyService.Stub mBinder = new IMyService.Stub() {

@Override
public List<Person> getPerson() throws RemoteException {
// TODO Auto-generated method stub
synchronized (mPersons) {
return mPersons;
}

}

@Override
public void addPerson(Person person) throws RemoteException {
// TODO Auto-generated method stub
synchronized (mPersons) {
if(!mPersons.contains(person)){
mPersons.add(person);
}
}
}
};


三、在AndroidManifest.xml文件中声明Service:

<service android:name="com.example.myaidlactivity.MyService"
android:process=":remote"
android:enabled="true">
<intent-filter >
<category
android:name="android.intent.category.DEFAULT"/>
<action
android:name="com.example.myservice.action"/>
</intent-filter>

</service>


说明:上述的 是为了能让其他apk通过action来隐式启动bindService,通过隐式调用的方式来起activity或者service,需要把category设为default,这是因为,隐式调用的时候,intent中的category默认会被设置为default。

以上完成后,新建一个工程来充当客户端。

四、新建一个工程来充当客户端。

1.新建一个名为TestAidlClient的工程充当客户端。把上面的服务端中整个package(com.zjt.myaidl)copy到本项目的src目录下,

工程结构如下:



这个时候,客户端com.zjt.myaidl包是和服务端工程完全一样的。

MainActivity.java:

public class MainActivity extends Activity {

private IMyService myService;
private List<Person> mPersons = new  ArrayList<Person>();
private Button bindService;

private final static String SERVICE_ACTION = "com.example.myservice.action";

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

bindService = (Button) findViewById(R.id.bindService);
bindService.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent mIntent = new Intent(SERVICE_ACTION);
bindService(mIntent, mServiceConnection, BIND_AUTO_CREATE);
}
});
}

private ServiceConnection mServiceConnection = new ServiceConnection() {

@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
myService = null;
}

@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
//通过服务端onBind方法返回的binder对象得到IMyService的实例,得到实例就可以调用它的方法了
myService = IMyService.Stub.asInterface(service);
try {
//通过IMyService接口来添加Person对象
myService.addPerson(new Person("wj", 26, "female"));
mPersons = myService.getPerson();
for(int i=0; i<mPersons.size();i++){
Person person = mPersons.get(i);
Log.e("----", "name = "+person.getName()+"\n age = "+person.getAge()+"\n sex = "+person.getSex());
Log.d("...", ".............");
}

} catch (Exception e) {
// TODO: handle exception
}
}
};

}


运行结果如下:



可以看到我们通过aidl的方式获取到另一apk的数据。

源码下载地址:http://download.csdn.net/detail/zhujiangtaotaise/9384987
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android ipc aidl