Android Binder原理解析(1)

public Stub() {

//这里的this代表IBookManager,注册了IInterface接口

this.attachInterface(this, DESCRIPTOR);

}

public void attachInterface(IInterface owner, String descriptor) {

mOwner = owner;

mDescriptor = descriptor;

}

这里我们发现穿进来的是个IInterface,IBookManager 继承自IInterface。

这时候服务端返回了个Binder,就到客户端了

/**

  • 连接器,通过调用Binder的方法去操作对象

*/

ServiceConnection connection = new ServiceConnection() {

@Override

public void onServiceConnected(ComponentName name, IBinder service) {

iBookManager = IBookManager.Stub.asInterface(service);

}

@Override

public void onServiceDisconnected(ComponentName name) {

iBookManager=null;

}

};

我们要调用 IBookManager.Stub.asInterface(service),这时候又会来到

//将一个IBinder对象转换成一个com.love.candy.aidl,这里就是我们平常用到的那个方法了

public static com.love.candy.aidl.IBookManager asInterface(android.os.IBinder obj) {

if ((obj == null)) {

return null;

}

//这里通过queryLocalInterface去查询有没有IInterface,

//这个在我们调用Stub构造方法的时候就已经穿进去了。就是那个this

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

//当获取到的不为空,并且是IBookManager,直接强转为IBookManager并返回

if (((iin != null) && (iin instanceof com.love.candy.aidl.IBookManager))) {

return ((com.love.candy.aidl.IBookManager) iin);

}

//否则就新创建一个Proxy

return new com.love.candy.aidl.IBookManager.Stub.Proxy(obj);

}

当我们去调用访问远程服务的方法iBookManager.addBook(book);就会调用到Proxy中的addBook方法。

@Override

public void addBook(com.love.candy.aidl.Book book) throws android.os.RemoteException {

//去获取序列化对象

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

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

try {

//把本aidl通过ndk写入到一个地方

_data.writeInterfaceToken(DESCRIPTOR);

//如果传入的值不是空

if ((book != null)) {

//把传入的值序列化

_data.writeInt(1);

book.writeToParcel(_data, 0);

} else {

_data.writeInt(0);

}

//调用了Binder的transact方法

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

_reply.readException();

} finally {

_reply.recycle();

_data.recycle();

}

}

把对象进行一些封装,他最终会调用mRemote.transact方法。

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

int flags) throws RemoteException {

if (false) Log.v(“Binder”, "Transact: " + code + " to " + this);

if (data != null) {

data.setDataPosition(0);

}

//这里会通过Binder的onTransact方法回调到我们Stub中

boolean r = onTransact(code, data, reply, flags);

if (reply != null) {

reply.setDataPosition(0);

}

return r;

}

这里会又回调到我们Stub中的onTransact。

@Override

public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply,

int flags) {

switch (code) {

case TRANSACTION_addBook: {

data.enforceInterface(DESCRIPTOR);

com.love.candy.aidl.Book _arg0;

//这里的值和Proxy中的值对应

if ((0 != data.readInt())) {

//通过data创建了个Book对象

_arg0 = com.love.candy.aidl.Book.CREATOR.createFromParcel(data);

} else {

_arg0 = null;

}

//回调抽象方法

this.addBook(_arg0);

reply.writeNoException();

return true;

}

}

return super.onTransact(code, data, reply, flags);

}

这里把我们传过来的对象进行解析,并回调了Stub的抽象方法addBook,这个抽象方法就是我们再Service中重写的那个方法

private class BookBind extends IBookManager.Stub {

@Override

public List getBookList() throws RemoteException {

return books;

}

@Override

public void addBook(Book book) throws RemoteException {

books.add(book);

Log.d(“lichao”," service addBook " + book.bookName);

}

}

最终调用了服务端中的addBook方法,把客户端加入的book加入到了服务端列表中。获取远程服务数据和加入数据流程差不多,只不过获取数据会有返回值。

流程图如下所示

引用了百度大神的图。

尾声

你不踏出去一步,永远不知道自己潜力有多大,千万别被这个社会套在我们身上的枷锁给捆住了,30岁我不怕,35岁我一样不怕,去做自己想做的事,为自己拼一把吧!不试试怎么知道你不行呢?

改变人生,没有什么捷径可言,这条路需要自己亲自去走一走,只有深入思考,不断反思总结,保持学习的热情,一步一步构建自己完整的知识体系,才是最终的制胜之道,也是程序员应该承担的使命。

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!
步一步构建自己完整的知识体系,才是最终的制胜之道,也是程序员应该承担的使命。

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

[外链图片转存中…(img-4ArRCaVj-1714482859384)]

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

  • 29
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值