这是一篇使用Android Studio写AIDL demo的文章,个人记录。
服务提供方,服务端。
创建AIDL文件。
package com.dc.myappAssist;
interface IMyAIDL {
int add(int a,int b);
}
创建之后将会在build\generated\aidl_source_output_dir下生成一个同名的java文件,它是一个接口,如下:
public interface IMyAIDL extends android.os.IInterface
{
/** Default implementation for IMyAIDL. */
public static class Default implements com.dc.myappAssist.IMyAIDL
{
@Override public int add(int a, int b) throws android.os.RemoteException
{
return 0;
}
@Override
public android.os.IBinder asBinder() {
return null;
}
}
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.dc.myappAssist.IMyAIDL {
...
}
}
接上,Service以Binder的形式对外提供服务。这个生成的接口内部包含一个Stub的抽象的静态内部类,继承于Binder,所以可以提供Service对外抛出;又它实现了AIDL接口,所以它又可以用于实现AIDL的业务。
创建服务,实现AIDL的业务并对外提供。onBind()的返回值用Stub的实现类。
public class MyAidlService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new IMyAIDL.Stub() {
@Override
public int add(int a, int b) throws RemoteException {
return a + b;
}
}
}
}
Service要对外提供,因此注册时,要提供隐式启动的方式(action启动),且export=‘true’。
服务调用方,即客户端。
将AIDL文件复制到客户端,切记不可修改包名。
然后启动服务,注意:1、跨进程要指定package,2、要以bindService的方式启动。
Intent i = new Intent(action);
i.setPackage("com.dc.myappAssist"); // 启动外部服务,要指定服务端的包名
bindService(i, new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
IMyAIDL aidl = IMyAIDL.Stub.asInterface(binder); // 客户端通过这个调用服务
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}, Context.BIND_AUTO_CREATE);
承上,IMyAIDL aidl = IMyAIDL.Stub.asInterface(binder),这是跨进程调用强转的方式,对比同进程的转换方式,IMyAIDL aidl = (IMyAIDL.Stub) binder),跨进程这么转会报错的,看源码。
public interface IMyAIDL extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.dc.myappAssist.IMyAIDL {
/**
* Cast an IBinder object into an com.dc.myappAssist.IMyAIDL interface,
* generating a proxy if needed.
*/
public static com.dc.myappAssist.IMyAIDL asInterface(android.os.IBinder obj) {
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.dc.myappAssist.IMyAIDL))) {
return ((com.dc.myappAssist.IMyAIDL)iin);
}
return new com.dc.myappAssist.IMyAIDL.Stub.Proxy(obj);
}
private static class Proxy implements com.dc.myappAssist.IMyAIDL {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
@Override public android.os.IBinder asBinder() {
return mRemote;
}
}
}
}
承上,bindService()得到的IBinder对象,是BinderProxy(class BinderProxy implements IBinder),客户端得到的是一个代理,用IMyAIDL.Stub.asInterface()。