/Fake_AIDL

不依赖AIDL工具,手写远程Service完成跨进程通信;

Primary LanguageJava

不依赖AIDL工具,手写远程Service完成跨进程通信

进程间通信:
1.Client 发起远程调用请求 也就是RPC 到Binder。同时将自己挂起,挂起的原因是要等待RPC调用结束以后返回的结果
2.Binder 收到RPC请求以后 把参数收集一下,调用transact方法,把RPC请求转发给service端。
3.service端 收到rpc请求以后 就去线程池里 找一个空闲的线程去走service端的 onTransact方法 ,实际上也就是
  真正在运行service端的 方法了,等方法运行结束 就把结果 写回到binder中。
4.Binder 收到返回数据以后 就唤醒原来的Client 线程,返回结果。至此,一次进程间通信 的过程就结束了

Stub 的构造方法:
private Binder mBinder = new IBookManager.Stub(){}
private Binder mBinder = new IBookManagerStub(){}

asInterface 方法:
asInterface 这个方法就做了一件事情:
如果在同一个进程,就返回 Stub 对象本身;
如果不在同一个进程,就返回 Stub.Proxy 代理对象;

onTransact 方法:
---------------------------------------------------------------------------------------
只有在多进程通信的时候 才会调用这个方法, 同一个进程是不会调用的;
这个方法一般情况下都是返回true的,如果返回false就代表这个方法执行失败;
通常使用这个方法做权限认证.

onTransact 这个方法是运行在 Binder 线程池中的,
一般就是 客户端发起请求,然后 android底层代码把这个客户端发起的请求 封装成 3个参数 来调用这个 onTransact 方法,
第一个参数 code 就代表客户端想要调用服务端 方法的 标志位;
	(服务端可能有n个方法,每个方法 都有一个对应的 int 值来代表, 这个 code 就是这个 int 值, 用来标示客户端想调用服务端的方法)
第二个参数 data 就是方法参数;
第三个参数 reply 就是方法返回值;

onTransact 这个方法运行在 Binder 线程池, 所以这个方法调用的服务端方法也是运行在 Binder 线程池中的,
所以我们的 服务端程序 有可能和多个客户端相关联, 所在方法里使用的这些参数 必须是支持异步的, 否则的话
值就会错乱了! 结论就是 Binder 方法, 一定是同步方法!!!!!!
---------------------------------------------------------------------------------------

Proxy 类:
在多进程通信的情况下,才会返回这个代理的对象;

/***************************************************************************************
 * 返回书籍列表;
 * 首先创建3个对象, _data 输入对象, _reply 输出对象, _result 返回值对象;
 * 然后把参数信息写入到 _data 里面, 接着就调用了 transact 这个方法 来发送 rpc 请求;
 * 然后当前线程挂起;
 * 服务端的 onTransace 方法被调用,调用结束以后,当前线程继续执行,
 * 直到从 _reply 中取出 rpc 的返回结果,然后返回 _reply 的数据;
 * 
 * 当客户端发起调用远程请求时,当前客户端的线程会被挂起,
 * 所以如果一个远程方法 很耗时, 客户端一定不能在 UI Main 线程里发起这个 RPC 请求,不然就 ANR 了.
 ***************************************************************************************/
@Override
public java.util.List<Book> getBookList() throws android.os.RemoteException {
	android.os.Parcel _data = android.os.Parcel.obtain();
	android.os.Parcel _reply = android.os.Parcel.obtain();
	java.util.List<dt.sprint.fackaidl.data.Book> _result;
    try {
        _data.writeInterfaceToken(DESCRIPTOR);
        mRemote.transact(IBookManagerStub.TRANSACTION_getBookList, _data, _reply, 0);
        _reply.readException();
        _result = _reply.createTypedArrayList(dt.sprint.fackaidl.data.Book.CREATOR);
    } finally {
        _reply.recycle();
        _data.recycle();
    }
    return _result;
}


参考资料:
http://www.cnblogs.com/punkisnotdead/p/5163464.html
http://www.jianshu.com/p/e642db926c50
http://weishu.me/2016/01/12/binder-index-for-newer