android进程间通信——aidl(Android Interface Definition Language)
2012-10-21 17:06
267 查看
在android中,通常情况下一个进程是不允许其它进程访问自己的内存的。而aidl提供了client和service都“同意”的交互接口,用以实现进程间通信。
使用aidl通常有三个阶段:
由于创建的是两个应用程序,为了方便介绍,这里先给出服务提供者(Service)的工程目录结构图:
一、aidl的设计——设计aidl包括三个步骤:
1、定义aidl
在设计好aidl接口后,就可以编写aidl文件了。aidl文件编写的语法和java语言的语法一样——后缀名改为.aidl,然后同时将它保存到服务提供者(service)和服务使用者(client)的源代码(src/derectory)目录下。
在上面的目录中,包含了两个aidl文件。其中,IDescribePerson.aidl是重点;Person.aidl是系统的需求,必须定义。
2、实现定义的aidl接口
android SDK 工具会为任何包含有.aidl文件的应用程序生成一个IBinder接口。根据.aidl文件生成的IBinder接口会保存在目录(gen/directory)下,该接口包含一个继承自Binder 的内部类—Stub。你只需要继承Stub类并实现该类的方法即可。
在上面目录中,RemoteService.java继承自Service,其中一成员变量mBinder为IDescribePerson.Stub的实现。
3、将接口暴露给用户
实现一个Service并且复写onBind()方法,该方法返回Stub类的实现类的实例。
RemoteService的onBind()方法返回mBinder。
(注意事项:aidl仅支持几种数据类型,包括:java所有的基本数据类型、String、CharSequence、List、Map、(Serializable、Parceable, 及其实现类))
二、进程间传递对象(Passing Objects Over IPC)
要实现进程间对象的传递,则该对象必须支持Parceable——类要实现Parceable接口。
上图中,类Person实现了Parceable接口。
三、调用进程通信方法(calling an IPC Method)——包括7个步骤:
下面将会用到client的相关内容,这里先将client目录结构图给出:
1、确保应用程序包含了aidl文件(如果嫌麻烦,可以直接将cxy.sh.aidl.server包下得内容直接拷贝过来)。
2、声明一个IBinder 的实例(该实例是基于AIDL文件生成的)。
3、实现ServiceConnection。
4、调用bindService(),传递参数ServiceConnection的实现。
5、在实现
6、调用接口中声明的方法。
7、调用方法
下面给出各文件的源码(文件内容是eclipse自动生成的就不贴了):
aidlTest应用:
Person.java
RemoteService.java
IDescribePerson.aidl
Person.aidl
package cxy.sh.aidl.server;
parcelable Person;
AndroidManifest.xml
aidlClient应用:
AidlClientActivity.java
使用aidl通常有三个阶段:
由于创建的是两个应用程序,为了方便介绍,这里先给出服务提供者(Service)的工程目录结构图:
一、aidl的设计——设计aidl包括三个步骤:
1、定义aidl
在设计好aidl接口后,就可以编写aidl文件了。aidl文件编写的语法和java语言的语法一样——后缀名改为.aidl,然后同时将它保存到服务提供者(service)和服务使用者(client)的源代码(src/derectory)目录下。
在上面的目录中,包含了两个aidl文件。其中,IDescribePerson.aidl是重点;Person.aidl是系统的需求,必须定义。
2、实现定义的aidl接口
android SDK 工具会为任何包含有.aidl文件的应用程序生成一个IBinder接口。根据.aidl文件生成的IBinder接口会保存在目录(gen/directory)下,该接口包含一个继承自Binder 的内部类—Stub。你只需要继承Stub类并实现该类的方法即可。
在上面目录中,RemoteService.java继承自Service,其中一成员变量mBinder为IDescribePerson.Stub的实现。
3、将接口暴露给用户
实现一个Service并且复写onBind()方法,该方法返回Stub类的实现类的实例。
RemoteService的onBind()方法返回mBinder。
(注意事项:aidl仅支持几种数据类型,包括:java所有的基本数据类型、String、CharSequence、List、Map、(Serializable、Parceable, 及其实现类))
二、进程间传递对象(Passing Objects Over IPC)
要实现进程间对象的传递,则该对象必须支持Parceable——类要实现Parceable接口。
上图中,类Person实现了Parceable接口。
三、调用进程通信方法(calling an IPC Method)——包括7个步骤:
下面将会用到client的相关内容,这里先将client目录结构图给出:
1、确保应用程序包含了aidl文件(如果嫌麻烦,可以直接将cxy.sh.aidl.server包下得内容直接拷贝过来)。
2、声明一个IBinder 的实例(该实例是基于AIDL文件生成的)。
3、实现ServiceConnection。
4、调用bindService(),传递参数ServiceConnection的实现。
5、在实现
onServiceConnected()方法时,调用YourInterfaceName.Stub.asInterface((IBinder)service)返回接口。
6、调用接口中声明的方法。
7、调用方法
Context.unbindService()断开与服务的连接。
下面给出各文件的源码(文件内容是eclipse自动生成的就不贴了):
aidlTest应用:
Person.java
package cxy.sh.aidl.server; import android.os.Parcel; import android.os.Parcelable; public class Person implements Parcelable { private String name ; private String telNumber ; private int age; public Person(Parcel p){ name = p.readString(); telNumber = p.readString(); age = p.readInt(); } public Person(){ } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getTelNumber() { return telNumber; } public void setTelNumber(String telNumber) { this.telNumber = telNumber; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int arg1) { dest.writeString(name); dest.writeString(telNumber); dest.writeInt(age); } public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>(){ @Override public Person createFromParcel(Parcel source){ return new Person(source); } @Override public Person[] newArray(int size){ return new Person[size]; } }; }
RemoteService.java
package cxy.sh.aidl.server; import java.util.LinkedList; import java.util.List; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; public class RemoteService extends Service { private LinkedList<Person> pList = new LinkedList<Person>(); @Override public IBinder onBind(Intent intent) { return mBinder; } private final IDescribePerson.Stub mBinder = new IDescribePerson.Stub(){ @Override public void savePersonInfo(Person person) throws RemoteException{ if(person != null){ pList.add(person); } } @Override public List<Person> getAllPerson() throws RemoteException{ return pList; } }; }
IDescribePerson.aidl
package cxy.sh.aidl.server; import cxy.sh.aidl.server.Person; interface IDescribePerson{ void savePersonInfo(in Person person); List<Person> getAllPerson(); }
Person.aidl
package cxy.sh.aidl.server;
parcelable Person;
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="cxy.sh.aidl.server" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="14" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:label="@string/app_name" android:name=".AidlTestActivity" > <intent-filter > <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name="RemoteService" > <intent-filter> <action android:name="cxy.sh.aidl.server.IDescribePerson"></action> </intent-filter> </service> </application> </manifest>
aidlClient应用:
AidlClientActivity.java
package cxy.sh.aidl.client; import java.util.List; import android.app.Activity; 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.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import cxy.sh.aidl.server.IDescribePerson; import cxy.sh.aidl.server.Person; public class AidlClientActivity extends Activity { private Button addPersonButton; private Button listPersonButton; private TextView inputPersonEdit; private IDescribePerson mRemoteService ; private ServiceConnection mRemoteCon = new ServiceConnection(){ @Override public void onServiceConnected(ComponentName name, IBinder service) { mRemoteService = IDescribePerson.Stub.asInterface(service); inputPersonEdit.setText("remote Servece connected !"); } @Override public void onServiceDisconnected(ComponentName name) { mRemoteService = null ; Log.e("tag", "remote Servece disconnected !"); } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); new Thread(new Runnable(){ @Override public void run() { Intent service = new Intent("cxy.sh.aidl.server.IDescribePerson"); bindService(service, mRemoteCon,BIND_AUTO_CREATE); ; } }).start(); addPersonButton = (Button) findViewById(R.id.btadd); listPersonButton = (Button) findViewById(R.id.btlist); inputPersonEdit = (TextView) findViewById(R.id.tv) ; addPersonButton.setOnClickListener( new View.OnClickListener(){ private int index = 0; @Override public void onClick(View view) { Person person = new Person(); index = index + 1; person.setName("person-->" + index); person.setAge(20+index); person.setTelNumber("123456-"+index); try { mRemoteService.savePersonInfo(person); } catch (RemoteException e) { e.printStackTrace(); } } }); listPersonButton.setOnClickListener( new View.OnClickListener(){ @Override public void onClick(View view) { List<Person> list = null; try { list = mRemoteService.getAllPerson(); } catch (RemoteException e) { e.printStackTrace(); } if (list != null){ StringBuilder text = new StringBuilder(); for(Person person : list){ text.append("\n联系人姓名:"); text.append(person.getName()); text.append("\n 年龄 :"); text.append(person.getAge()); text.append("\n 电话号码:"); text.append(person.getTelNumber()+"\n"); } inputPersonEdit.setText(text); }else { Toast.makeText(AidlClientActivity.this, "get data error", Toast.LENGTH_SHORT).show(); } } }); } @Override protected void onPause() { super.onPause(); unbindService(mRemoteCon); } }
相关文章推荐
- Android Interface Definition Language (AIDL) 接口描述语言
- Android Interface Definition Language (AIDL) android接口定义语言 开发文档翻译 - 1
- Android AIDL(Android Interface Definition Language)介绍
- 安卓接口语言 Android Interface Definition Language (AIDL)
- 【翻译】Android Interface Definition Language (AIDL)
- Android AIDL(Android Interface Definition Language)介绍
- Android Interface Definition Language (AIDL)
- Android Interface Definition Language (AIDL)
- Android接口描述语言-Android Interface Definition Language (AIDL)
- Android Interface Definition Language (AIDL)
- Android AIDL(Android Interface Definition Language)介绍
- Android Interface Definition Language (AIDL)实现应用间通信
- Android Interface Definition Language (AIDL)——翻译自developer.android.com
- Android Interface Definition Language (AIDL)详解
- AIDL(Android Interface Definition Language)
- AIDL(Android Interface Definition Language)
- AIDL(Android Interface definition language)学习笔记一
- Android Interface Definition Language (AIDL) android接口定义语言 开发文档翻译 - 2
- Android Interface Definition Language (AIDL)
- Android AIDL(Android Interface Definition Language)介绍