1:谈一下handler的原理
handler主要有4个组成部分,分别是:
Message,MessageQueue,Handler,Looper
Message用来存放数据
MessageQueue是一个消息队列,用来存取Message
Handler负责发送和获取数据
Looper是一个循环,用来不断查看在MessageQueue中是否有新的Message进来
2:handler的作用
最大的作用就是异步处理消息,因为handler是在主线程创建,因此子线程通过handler发送的消息会被handler在主线程中使用,这样就实现了异步消息的处理
2:谈一下AIDL原理
默认支持的数据类型包括:
1.Java中的八种基本数据类型,包括byte、short、int、long、float、double、boolean、char;
2.String类型、CharSequence类型;
3.List类型:List中的所有元素必须是AIDL支持的类型之一,或者是一个其他AIDL生成的接口,或者是定义的parcelable(下文关于这个会有详解)。List可以使用泛型;
4.Map类型:Map中的所有元素必须是AIDL支持的类型之一,或者是一个其他AIDL生成的接口,或者是定义的parcelable。Map是不支持泛型的;
5.定向tag:out in
6.序列化以后的实体类
原理
简单来说,AIDL 就是定义一个接口,客户端(调用端)通过 bindService 来与远程服务端建立一个连接,在该连接建立时会将返回一个 IBinder 对象,该对象是服务端 Binder 的 BinderProxy。在建立连接时,客户端通过 asInterface 函数将该 BinderProxy 对象包装成本地的 Proxy,并赋值给Proxy类的 mRemote 字段,本地通过 mRemote 即可调用远程方法。
说到aidl不得不提到binder,Android进程分为用户空间和内核空间,因为用户空间互不连通,因此进程间不可通讯,如果想进程间通讯就需要用到binder,binder可以为用户空间在内核空间开辟一个空间,通过这个共享的内核空间,用户空间之间就可以通讯了,也就是进程之间就可以通讯了。
那么aidl中是如何使用binder的呢?首先Service的onBind方法提供一个Ibinder
@Override
public IBinder onBind(Intent intent) {
GwmLog.d(TAG,"onBind");
return mMediaControlImpl.getRemoteControls();
}
这个Ibinder我们给它提供一个aidl文件中的stub,这个stub继承了binder,因此stub具有binder的功能
public static abstract class Stub extends android.os.Binder implements com.gwm.app.media.common.aidl.ITransportControls
{
......
}
客户端bindService的时候,通过可以通过Ibinder获取到一个Stub.Proxy
IMyAidlInterface mService = IMyAidlInterface.Stub.asInterface((IBinder) service);
Stub.Proxy为服务端Stub的代理,又因为服务端Stub具有binder的功能,binder又具有跨进程通讯功能,因此客户端可以通过Stub.Proxy去调用service中方法
public static com.gwm.app.media.common.aidl.ITransportControls asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.gwm.app.media.common.aidl.ITransportControls))) {
return ((com.gwm.app.media.common.aidl.ITransportControls)iin);
}
return new com.gwm.app.media.common.aidl.ITransportControls.Stub.Proxy(obj);
}