Android中进程间通讯(IPC)方式之一AIDL机制

来源:互联网 发布:linux 有道云笔记 编辑:程序博客网 时间:2024/05/15 23:46

Android进程间通信方式有多种,今天讲解一下AIDL的使用方法。

AIDL(Android Interface Definition Language)是Android进程间通讯独特的通讯方式,通过绑定Service来实现。

下面以Demo的形式开始今天的讲解,Demo演示通过在客户端(程序A中的Activity)读取服务端(程序B中的Service)的数据,这里的数据是一个对象--继承了Parcelable的People类。

要在进程间通信传递复杂的对象需要以下操作:

  1. 子类实现Parcelable接口,意味着要实现writeToParcel()和readFromParcel(),writeToParcel()方法将对象写入到包裹(parcel)中,而readFromParcel()方法从包裹中读取对象。注意,写入的顺序必须与读取的顺序相同。
  2. 向该类添加一个名为CREATOR的static final 属性,该属性需要实现android.os.Parcelable.Creatot<T>接口。
  3. 为Parcelable提供一个构造函数,该函数知道如何从Parcelable创建对象。
  4. 在与包含复杂类型的的.java文件匹配的.aidl文件中定义Parcelable类,AIDL编译器在编译AIDL文件时将查找此文件,且要与对应的.java文件放在同一位置下。
  5. 项目中每个Parcelable都需要一个.aidl文件。

1子类People实现Parcelable

package com.test.aidl;import android.os.Parcel;import android.os.Parcelable;public class People implements Parcelable {public String name;public int age;public int height;public String ID;public String address;public String tel;public String gender;// 性别public static final Parcelable.Creator<People> CREATOR = new Creator<People>() {@Overridepublic People[] newArray(int size) {// TODO Auto-generated method stubreturn new People[size];}@Overridepublic People createFromParcel(Parcel source) {// TODO Auto-generated method stubreturn new People(source);}};public People() {}public People(Parcel source) {// TODO Auto-generated constructor stubreadFromParcel(source);}@Overridepublic int describeContents() {// TODO Auto-generated method stubreturn 0;}@Overridepublic void writeToParcel(Parcel dest, int flags) { // TODO Auto-generated// method stubdest.writeString(name);dest.writeInt(age);dest.writeInt(height);dest.writeString(ID);dest.writeString(address);dest.writeString(gender);}        @Overridepublic void readFromParcel(Parcel parcel) {name = parcel.readString();age = parcel.readInt();height = parcel.readInt();ID = parcel.readString();address = parcel.readString();tel = parcel.readString();gender = parcel.readString();}}

People.aidl文件示例:

package com.test.aidl;parcelable People;

定义一个ServiceTest类继承Service:

@Overridepublic IBinder onBind(Intent arg0) {// TODO Auto-generated method stubreturn new sserviceTest();}public class sserviceTest extends AAAA.Stub{@Overridepublic People getPeople(String ID) throws RemoteException {      // TODO Auto-generated method stub      People people = new People();      people.name = "高芳";      people.age = 22;      people.address = "山东.东营";      people.gender ="女";      people.height = 161;      people.tel = "未知";      people.ID = ID;      return people;}}


编写.aidl文件:

package com.test.aidl;import com.test.aidl.People;interface AAAA{       People getPeople(String ID);}


AndroidMainfest.xml配置

<manifest xmlns:android="http://schemas.android.com/apk/res/android"      package="com.example.service"      android:versionCode="1"      android:versionName="1.0" >          <uses-sdk          android:minSdkVersion="8"          android:targetSdkVersion="15" />          <application          android:icon="@drawable/ic_launcher"          android:label="@string/app_name"          android:theme="@style/AppTheme" >     <service android:name=".ServiceTest">     <intent-filter>       <action android:name="com.inent.action.AAAA"/>        </intent-filter>     </service>         </application>  </manifest>  

注意:客户端要调用服务端,把定义的接口文件(.aidl)拷过来,并且包名要跟服务端一样。

客户端:

bt.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {       // TODO Auto-generated method stub       bindService(new Intent("com.inent.action.AAAA"), serviceConnection, Service.BIND_AUTO_CREATE);       People people = null;       try {            people = mAaaa.getPeople("100");            mTextView.setText("姓名:" + people.name + "\n" + "性别:" + people.gender + "\n" + "年龄:" + people.age             +"\n" + "地址:" + people.address + "\n" + "" );       } catch (RemoteException e) {            // TODO Auto-generated catch block            e.printStackTrace();       }    }});


运行时报错,上面红色的那一行报:02-27 14:59:42.699: E/AndroidRuntime(32440): java.lang.NullPointerException

mAaaa是空指针,开始以为绑定没有成功,查看了一下没问题,问题出在,绑定服务时需要异步获取对象,这里开启一个线程获取对象就ok了

bt.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubbindService(new Intent("com.inent.action.AAAA"), serviceConnection, Service.BIND_AUTO_CREATE);mHandler.post(runnable);}});public Runnable runnable = new Runnable() {@Overridepublic void run() {       // TODO Auto-generated method stub       mHandler.obtainMessage(100).sendToTarget();       }};public Handler mHandler = new Handler(){         @Override         public void handleMessage(Message msg) {              // TODO Auto-generated method stub              super.handleMessage(msg);              People people = null;              people = getPeople();              mTextView.setText("姓名:" + people.name + "\n" + "性别:" + people.gender + "\n" + "年龄:" + people.age               +"\n" + "地址:" + people.address + "\n" + "" );}};


源码下载(Demo):点击打开链接

原创粉丝点击