Android Binder原理解析,安卓rxjava获取网络时间

  • 基本数据类型(int、long、char、boolean、double等)

  • String 和CharSequence

  • List:只支持ArrayList,里面每个元素都必须能够被AIDL支持

  • Map:只支持HashMap,里面的每个元素都必须被AIDL支持,包括key。

  • Parcelable:所有实现了Parcelable接口的对象。

  • AIDL:所有的AIDL接口本身也可以在AIDL中使用。

AIDL生成结构图在这里插入图片描述
下面我们实现一个简单的AIDL并分析一下他的通信过程

Intent intent = new Intent(this, MyService.class);

bindService(intent,connection,BIND_AUTO_CREATE);

当我们调用bindService方法后。系统就会为我们把对应的远程服务端唤醒,看源码知道是通过ServiceManager 去远程服务用ClassLoader反射的方式启动需要启动的service。细节部分大家自己看frameWork层源码吧,东西太多了,这里只分析AIDL应用层流程。

Service启动之后就开始去创建BookBind类

@Override

public IBinder onBind(Intent intent) {

return new BookBind();

}

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);

}

}

这个类又会去

AIDLDemo\app\build\generated\source\aidl\debug\com\love\candy\aidl\IBookManager.java

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的方法去操作对象

*/

ServiceCon

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享

nection 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())) {

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值