public void basicTypes(int anInt, long aLong, boolean aBoolean,
float aFloat, double aDouble, String aString) {
// Does nothing
System.out.println("basicTypes");
}
};
/**
- 实现定义的aidl接口。
*/
private final IRemoteService2.Stub mBinder2 = new IRemoteService2.Stub() {
@Override
public void sysout() {
System.out.println("This is IremoteService2.Stub.sysout()");
}
@Override
public String returnStr() throws RemoteException {
return "This is IRemoteServicfe2.Stub.returnStr()";
}
};
3、向客户端公开(暴露)接口-如果是编写服务,应该继承Service并且重载Service.onBind(Intent) 以返回实现了接口的对象实例
/**
- 返回IBinder,在这里可以根据选择的接口进行返回哪一个 如果只有一个接口就不需要判断,直接返回就可以了。
*/
@Override
public IBinder onBind(Intent intent) {
if (IRemoteService2.class.getName().equals(intent.getAction())) {
return mBinder2;
}
if (IRemoteService.class.getName().equals(intent.getAction())) {
return mBinder;
}
return null;
}
4、 运行这个程序,那么服务就已经安装到系统了。接下来就是客户端访问服务,利用服务,进行进程间的通信。
下面再看看如何调用IPC 方法(Calling an IPC Method)
1、 声明.aidl 文件中定义的接口类型的变量和方法。
IRemoteService.aidl
package hb.android.aidl;
interface IRemoteService {
int getPid();
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);
}
IRemoteService2.aidl
package hb.android.aidl;
interface IRemoteService2 {
void sysout();
String returnStr();
}
2、 实现ServiceConnection
/**
-
ServiceConnection与Service想链接,IRemoteService.Stub.asInterface(service);
-
会返回与当前的aidl文件相关的类的实例,这样就可以获取到远程的远程服务实现的IRemoteService接口了。
-
注意如果一个ServiceConnection同一时刻只能与Service连接
-
。如果需要同时连接一个服务里的多个aidl接口,那么必须定义两个ServiceConnection获取
-
,因为一个ServiceConnection连接会返回一个aidl接口的实例。
*/
private ServiceConnection mConnection = new ServiceConnection() {
// Called when the connection with the service is established
public void onServiceConnected(ComponentName className, IBinder service) {
// Following the example above for an AIDL interface,
// this gets an instance of the IRemoteInterface, which we can use
// to call on the service
try {
if (service.getInterfaceDescriptor().equals(
IRemoteService.class.getName())) {
mIRemoteService = IRemoteService.Stub.asInterface(service);
mIRemoteService.basicTypes(0, 0, false, 0, 0, null);
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
// Called when the connection with the service disconnects unexpectedly
public void onServiceDisconnected(ComponentName className) {
System.out.println("Service has unexpectedly disconnected");
mIRemoteService = null;
}
};
private ServiceConnection mConnection2 = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
System.out.println("Service2 has unexpectedly disconnected");
mIRemoteService2 = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
try {
if (service.getInterfaceDescriptor().equals(
IRemoteService2.class.getName())) {
mIRemoteService2 = IRemoteService2.Stub
.asInterface(service);
mIRemoteService2.sysout();
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
};
3、 调用Context.bindService(),传递ServiceConnection的实现
intent = new Intent(IRemoteService.class.getName());
System.out.println(IRemoteService.class.getName());
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
intent2 = new Intent(IRemoteService2.class.getName());
System.out.println(IRemoteService2.class.getName());
bindService(intent2, mConnection2, BIND_AUTO_CREATE);
4、 在ServiceConnection.onServiceConnected()方法中会接收到IBinder对象,调用YourInterfaceName.Stub.asInterface((IBinder)service)将返回值转换为YourInterface类型
mIRemoteService = IRemoteService.Stub.asInterface(service);
mIRemoteService.basicTypes(0, 0, false, 0, 0, null);
5、 调用接口中定义的方法。应该总是捕获连接被打断时抛出的DeadObjectException异常,这是远端方法唯一的异常。
6、 调用Context.unbindService()断开连接;
protected void onDestroy() {
super.onDestroy();
unbindService(mConnection);
unbindService(mConnection2);
};
如果想利用进程间的通信来传递对象,那么该对象必须实现Parcelable,下面详细步骤:
1、 使该类实现Parcelabel接口。
package hb.android.entry;
import android.os.Parcel;
import android.os.Parcelable;
/**
-
在进行间通信必须实现Parcelable接口
-
@author Administrator
*/
public class Person implements Parcelable {
public String name;
public String sex;
public String tel;
public Person() {
super();
}
public Person(Parcel in) {
readFromParcel(in);
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
/**
- 实现从in中创建出类的实例的功能
*/
public Person createFromParcel(Parcel in) {
return new Person(in);
}
/**
- 创建一个类型为T,长度为size的数组,仅一句话(return new T[size])即可。估计本方法是供外部类反序列化本类数组使用。
*/
public Person[] newArray(int size) {
return new Person[size];
}
};
/**
-
从一个外部的Parcel对象读取对象。顺序必须与writeToParcel对应,不然会出错。
-
@param in
*/
public void readFromParcel(Parcel in) {
name = in.readString();
sex = in.readString();
tel = in.readString();
}
/**
- 该方法将类的数据写入外部提供的Parcel中
*/
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(sex);
dest.writeString(tel);
}
/**
- 没搞懂有什么用,反正直接返回0也可以
*/
@Override
public int describeContents() {
return 0;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;