Android进程间通讯一AIDL机制

源码下载:点击打开链接

我们可以使用AIDL来实现跨进程的方法调用,理解AIDL我们需要理解Binder的概念,如果我们对Binder有了一定的了解,在Binder基础上我们可以更加容易地理解AIDL。

名词解析:IPC(Inter-process Communication )跨进程通信。

AIDL(Android Interface Definition Language)Android接口定义语言。

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>() {
		@Override
		public People[] newArray(int size) {
			// TODO Auto-generated method stub
			return new People[size];
		}

		@Override
		public People createFromParcel(Parcel source) {
			// TODO Auto-generated method stub
			return new People(source);
		}
	};

	public People() {
	}

	public People(Parcel source) {
		// TODO Auto-generated constructor stub
		readFromParcel(source);
	}

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

	@Override
	public void writeToParcel(Parcel dest, int flags) { // TODO Auto-generated
														// method stub
		dest.writeString(name);
		dest.writeInt(age);
		dest.writeInt(height);
		dest.writeString(ID);
		dest.writeString(address);
		dest.writeString(gender);
	}
        @Override
	public 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:

@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return new sserviceTest();
}
public class sserviceTest extends AAAA.Stub{
@Override
public 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() {

@Override
public 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() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
bindService(new Intent("com.inent.action.AAAA"), serviceConnection, Service.BIND_AUTO_CREATE);
mHandler.post(runnable);
}
});
public Runnable runnable = new Runnable() {

@Override
public 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" + "" );
}

};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值