Android AIDL接口方法详解
2017-09-25 16:30
645 查看
有关AIDL的使用我就不多说了,今天主要讲的是AIDL的方法作用
AIDL是定义接口的一种语言,多使用跨进程通信的场景,比方说你现在需要获取到服务端的数据(这个服务端不是指提供接口的后台,而是与你当前应用不在一个进程的程序),这个时候你就需要跨进程去获取数据了.
OK,我们先看一下系统生成的AIDL接口:
public interface GetTokenService extends android.os.IInterface {
/**
* Local-side IPC implementation stub class.
* 内部类的实现
* 实际上这个stub类就是一个binder类,我会对每个方法都一个解释,然后再做一下总结
*/
public static abstract class Stub extends android.os.Binder implements com.sumaott.auth.service.GetTokenService {
}
注: GetTokenService 是类名,这个你可以自己去定义,getToken()方法是获取对应数据的一个类,你在获取数据时,需改成与服务端对应的数据结构和方法名
整个运行的逻辑: 首先使用整型ID去标识方法,如果有两个方法则再加一个整型ID,,接着声明了一个内部类stub类,然后通过asInterface方法去判断当前在是否在同一进程中,如果在,返回Stub对象,否则返回Stub.proxy对象, ,,在返回Stub.proxy对象之前会去执行Stub的Proxy内部代理类,然后在Proxy类里去调用transact方法来启动RPC(远程调用服务),同时会将当前线程挂起,然后onTransact方法会被执行,并将获取到的数据写入reply中,然后等到RPC过程结束后,回到当前线程也就是Proxy类里的getToken() 方法,然后获取到RPC之前写入在reply中的数据,最终我们就可以拿到对应的数据了
备注:RPC是耗时服务,不要在UI线程里去做这步操作
AIDL是定义接口的一种语言,多使用跨进程通信的场景,比方说你现在需要获取到服务端的数据(这个服务端不是指提供接口的后台,而是与你当前应用不在一个进程的程序),这个时候你就需要跨进程去获取数据了.
OK,我们先看一下系统生成的AIDL接口:
public interface GetTokenService extends android.os.IInterface {
/**
* Local-side IPC implementation stub class.
* 内部类的实现
* 实际上这个stub类就是一个binder类,我会对每个方法都一个解释,然后再做一下总结
*/
public static abstract class Stub extends android.os.Binder implements com.sumaott.auth.service.GetTokenService {
private static final java.lang.String DESCRIPTOR = "当前类的路径,会自动生成"; //标识方法 /** * Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); } /** * Cast an IBinder object into an com.sumaott.auth.service.GetTokenService interface, * generating a proxy if needed. * 将服务端的binder对象转换成客户端所需要的AIDL对象,如果在同进程中,返回stub本身,否则返回stub.proxy * 我们可以看代码 */ public static com.sumaott.auth.service.GetTokenService asInterface(android.os.IBinder obj) { if ((obj == null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin != null) && (iin instanceof com.sumaott.auth.service.GetTokenService))) { //这里是区分是否在一个进程中 **return ((com.sumaott.auth.service.GetTokenService) iin);** // 返回stub本身 } **return new com.sumaott.auth.service.GetTokenService.Stub.Proxy(obj);** 否则返回stub.proxy } @Override public android.os.IBinder asBinder() { //返回当前的Binder对象 return this; } @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException { //通过code确定客户端请求的目标方法是什么, switch (code) { case INTERFACE_TRANSACTION: { //接口错误,没找到对应的目标方法 reply.writeString(DESCRIPTOR); return true; } case TRANSACTION_getToken: { //如果找到了对应的目标方法,执行方法,再向reply中写入返回值_result data.enforceInterface(DESCRIPTOR); java.lang.String _result = this.getToken(); reply.writeNoException(); reply.writeString(_result); return true; } } return super.onTransact(code, data, reply, flags); } //这个方法是运行在客户端的 private static class Proxy implements com.sumaott.auth.service.GetTokenService { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } @Override public android.os.IBinder asBinder() { return mRemote; } public java.lang.String getInterfaceDescriptor() { return DESCRIPTOR; } /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ @Override public java.lang.String getToken() throws android.os.RemoteException { //创建输入型对象_data,输出型对象_reply,返回值对象_result android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); java.lang.String _result; try { _data.writeInterfaceToken(DESCRIPTOR); //调用transact方法来发起RPC请求,同时将当期线程挂起,等待服务端的onTransact方法被调用直到RPC过程返 回,当期线程继续执行 mRemote.transact(Stub.TRANSACTION_getToken, _data, _reply, 0); _reply.readException(); _result = _reply.readString(); } finally { _reply.recycle(); _data.recycle(); } return _result; //在将获取到的值返回 } } static final int TRANSACTION_getToken = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); } /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ public java.lang.String getToken() throws android.os.RemoteException;
}
注: GetTokenService 是类名,这个你可以自己去定义,getToken()方法是获取对应数据的一个类,你在获取数据时,需改成与服务端对应的数据结构和方法名
整个运行的逻辑: 首先使用整型ID去标识方法,如果有两个方法则再加一个整型ID,,接着声明了一个内部类stub类,然后通过asInterface方法去判断当前在是否在同一进程中,如果在,返回Stub对象,否则返回Stub.proxy对象, ,,在返回Stub.proxy对象之前会去执行Stub的Proxy内部代理类,然后在Proxy类里去调用transact方法来启动RPC(远程调用服务),同时会将当前线程挂起,然后onTransact方法会被执行,并将获取到的数据写入reply中,然后等到RPC过程结束后,回到当前线程也就是Proxy类里的getToken() 方法,然后获取到RPC之前写入在reply中的数据,最终我们就可以拿到对应的数据了
备注:RPC是耗时服务,不要在UI线程里去做这步操作
相关文章推荐
- 详解Android中接口回调、方法回调
- Android ViewPager切换之PageTransformer接口中transformPage方法position参数使用详解
- Android Parcelable接口使用方法详解
- Android AIDL使用方法详解
- Android ViewPager切换之PageTransformer接口中transformPage方法position参数使用详解
- 方法接口Service与AIDL详解
- Android AIDL(安卓接口定义语言)基本使用方法
- Android AIDL(接口定义语言)简单理解和基本使用方法
- [Root权限/提取] i9000 android 2.2 目前最简单root和data to 2G的方法及详解
- Android系列之浅谈AndroidGallery控件使用方法详解
- AIDL --- Android中的远程接口
- Android判断网络状态方法详解
- Android Adapter 接口中几个方法的研究
- Android Adapter 接口中几个方法的研究
- 详解Android实现全屏正确方法
- Android之TelephonyManager类的方法详解
- AIDL --- Android中的远程接口
- Android开发中实现跨进程通讯的AIDL接口
- AIDL-- Android中的远程接口 [转]
- AIDL --- Android中的远程接口