您的位置:首页 > 大数据 > 人工智能

AIDL——实现机制浅析

2014-09-16 19:40 399 查看
aidl是 Android Interface definition language的缩写,它是一种进程通信接口的描述,通过sdk解释器对器进行编译,会把它编译成java代码在gen目录下,类路径与aidl文件的类路径相同。

  3.aidl接口

package com.cao.android.demos.binder.aidl;  

import com.cao.android.demos.binder.aidl.AIDLActivity;

interface AIDLService {   

    void registerTestCall(AIDLActivity cb);   

    void invokCallBack();

}

它编译后生成的java文件如下



AIDLService.java详细描述了aidl接口的实现,看上面图示,AIDLActivity.aidl编译成了一个接口AIDLActivity,一个存根类Stub,一个代理类Proxy

public interface AIDLService extends android.os.IInterface//与AIDLActivity.aidl中定义的接口对应的java接口实现

public static abstract class Stub extends android.os.Binder implements com.cao.android.demos.binder.aidl.AIDLService

//继承android.os.Binder,在onTransact完成对通信数据的接收,通过不同通信参数code调用AIDLService接口方法,并回写调用返回结果AIDLService接口方法需要在

//服务端实现

private static class Proxy implements com.cao.android.demos.binder.aidl.AIDLService

//实现AIDLService接口方法,但是方法只是执行代理远程调用操作,具体方法操作在远端的Stub存根类中实现

 

总的来说,AIDLActivity.aidl编译会生成一个AIDLActivity接口,一个stub存根抽像类,一个proxy代理类,这个实现其实根axis的wsdl文件编译生成思路是一致的,

stub存根抽像类需要在服务端实现,proxy代理类被客户端使用,通过stub,proxy的封装,屏蔽了进程通信的细节,对使用者来说就只是一个AIDLActivity接口的调用

 

  4.根据以上思路使用aidl再看一下AIDLService调用实现代码

--1.在服务端实现AIDLService.Stub抽象类,在服务端onBind方法中返回该实现类

--2.客户端绑定service时在ServiceConnection.onServiceConnected获取onBind返回的IBinder对象

        private ServiceConnection mConnection = new ServiceConnection() {

                public void onServiceConnected(ComponentName className, IBinder service) {

                        Log("connect service");

                        mService = AIDLService.Stub.asInterface(service);

                        try {

                                mService.registerTestCall(mCallback);

                        } catch (RemoteException e) {

                        }

                }

        注意mConnection在bindservice作为调用参数:bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

--3.AIDLService.Stub.asInterface(service);

public static com.cao.android.demos.binder.aidl.AIDLService asInterface(android.os.IBinder obj)

{

if ((obj==null)) {

return null;

}

android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);

//如果bindService绑定的是同一进程的service,返回的是服务端Stub对象本省,那么在客户端是直接操作Stub对象,并不进行进程通信了

if (((iin!=null)&&(iin instanceof com.cao.android.demos.binder.aidl.AIDLService))) {

return ((com.cao.android.demos.binder.aidl.AIDLService)iin);

}

//bindService绑定的不是同一进程的service,返回的是代理对象,obj==android.os.BinderProxy对象,被包装成一个AIDLService.Stub.Proxy代理对象

//不过AIDLService.Stub.Proxy进程间通信通过android.os.BinderProxy实现

return new com.cao.android.demos.binder.aidl.AIDLService.Stub.Proxy(obj);

}

--4.调用AIDLService接口方法,如果是同一进程,AIDLService就是service的Stub对象,等同直接调用Stub对象实现的AIDLService接口方法

如果是一个proxy对象,那就是在进程间调用了,我们看一个客户端调用的例子:

                        public void onClick(View v) {

                                Log("AIDLTestActivity.btnCallBack");

                                try {

                                        mService.invokCallBack();

                                } catch (RemoteException e) {

                                        // TODO Auto-generated catch block

                                        e.printStackTrace();

                                }

        --mService.invokCallBack()等同调用Proxy.invokCallBack,这个时候是进程间调用,我们看代理方法的实现

public void invokCallBack() throws android.os.RemoteException

{

//构造一个Parcel对象,该对象可在进程间传输

android.os.Parcel _data = android.os.Parcel.obtain();

android.os.Parcel _reply = android.os.Parcel.obtain();

try {

//DESCRIPTOR = "com.cao.android.demos.binder.aidl.AIDLService",描述了调用哪个Stub对象

_data.writeInterfaceToken(DESCRIPTOR);

//Stub.TRANSACTION_invokCallBack标识调用Stub中哪个接口方法,mRemote在是构造Proxy对象的参数obj,也就是public void onServiceConnected(ComponentName className, IBinder service)

//中的service参数,它是一个BinderProxy对象,负责传输进程间数据。

mRemote.transact(Stub.TRANSACTION_invokCallBack, _data, _reply, 0);

_reply.readException();

}

finally {

_reply.recycle();

_data.recycle();

}

}

--5.BinderProxy.transact 该方法本地化实现

   public native boolean transact(int code, Parcel data, Parcel reply,

            int flags) throws RemoteException;

        //对应实现的本地化代码 /frameworks/base/core/jni/android_util_Binder.cpp->static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,

                                                jint code, jobject dataObj,

                                                jobject replyObj, jint flags)

  //具体进程通信在c代码中如何实现,以后再深入研究。

--6.服务端进程数据接收

        --调用堆栈

        ##AIDLService.Stub.onTransact

        ##AIDLService.Stub(Binder).execTransact

        ##NativeStart.run

        --AIDLService.Stub.onTransact

        public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException

{

switch (code)

{

case INTERFACE_TRANSACTION:

{

reply.writeString(DESCRIPTOR);

return true;

}

case TRANSACTION_registerTestCall:

{

data.enforceInterface(DESCRIPTOR);

com.cao.android.demos.binder.aidl.AIDLActivity _arg0;

_arg0 = com.cao.android.demos.binder.aidl.AIDLActivity.Stub.asInterface(data.readStrongBinder());

this.registerTestCall(_arg0);

reply.writeNoException();

return true;

}

//TRANSACTION_invokCallBack由前面客户端调用的时候transact方法参数决定,code==TRANSACTION_invokCallBack,执行

//invokCallBack方法,方法由继承Stud的服务端存根类实现。

case TRANSACTION_invokCallBack:

{

data.enforceInterface(DESCRIPTOR);

this.invokCallBack();

reply.writeNoException();

return true;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  AIDL IPC