IPC基础小记 关于Binder
来源:互联网 发布:怎么申请网站域名 编辑:程序博客网 时间:2024/06/05 11:12
Binder是Android中的一个类,它实现了IBinder接口。
从IPC角度来说Binder是Android中的一种跨进程通信方式
Binder是桥梁,Binder是媒介。。。给笔者印象Binder就是个顺丰。。。
我们可以通过AIDL文件生成一个Binder类
新建一个文件后缀改成.aidl敲如下代码
package com.example.testandroid;
parcelable Book;
新建一个文件后缀改成.aidl 敲如下代码
package com.example.testandroid;
import com.example.testandroid.Book;
interface IBookManager{
List<Book>getBookList();
void addBook(in Book book);
}
系统会生成一个IBookManager.java类
/* * This file is auto-generated. DO NOT MODIFY. * Original file: */package com.example.testandroid;public interface IBookManager extends android.os.IInterface { /** Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements com.example.testandroid.IBookManager { private static final java.lang.String DESCRIPTOR = "com.example.testandroid.IBookManager"; /** Construct the stub at attach it to the interface. */ public Stub() { this.attachInterface(this, DESCRIPTOR); } /** * Cast an IBinder object into an com.example.testandroid.IBookManager * interface, generating a proxy if needed. */ public static com.example.testandroid.IBookManager asInterface(android.os.IBinder obj) { if ((obj == null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin != null) && (iin instanceof com.example.testandroid.IBookManager))) { return ((com.example.testandroid.IBookManager) iin); } return new com.example.testandroid.IBookManager.Stub.Proxy(obj); } @Override public android.os.IBinder asBinder() { return this; } @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException { switch (code) { case INTERFACE_TRANSACTION: { reply.writeString(DESCRIPTOR); return true; } case TRANSACTION_getBookList: { data.enforceInterface(DESCRIPTOR); java.util.List<com.example.testandroid.Book> _result = this.getBookList(); reply.writeNoException(); reply.writeTypedList(_result); return true; } case TRANSACTION_addBook: { data.enforceInterface(DESCRIPTOR); com.example.testandroid.Book _arg0; if ((0 != data.readInt())) { _arg0 = com.example.testandroid.Book.CREATOR.createFromParcel(data); } else { _arg0 = null; } this.addBook(_arg0); reply.writeNoException(); return true; } } return super.onTransact(code, data, reply, flags); } private static class Proxy implements com.example.testandroid.IBookManager { 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; } @Override public java.util.List<com.example.testandroid.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<com.example.testandroid.Book> _result; try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_getBookList, _data, _reply, 0); _reply.readException(); _result = _reply.createTypedArrayList(com.example.testandroid.Book.CREATOR); } finally { _reply.recycle(); _data.recycle(); } return _result; } @Override public void addBook(com.example.testandroid.Book book) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); try { _data.writeInterfaceToken(DESCRIPTOR); if ((book != null)) { _data.writeInt(1); book.writeToParcel(_data, 0); } else { _data.writeInt(0); } mRemote.transact(Stub.TRANSACTION_addBook, _data, _reply, 0); _reply.readException(); } finally { _reply.recycle(); _data.recycle(); } } } static final int TRANSACTION_getBookList = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0); static final int TRANSACTION_addBook = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1); } public java.util.List<com.example.testandroid.Book> getBookList() throws android.os.RemoteException; public void addBook(com.example.testandroid.Book book) throws android.os.RemoteException;}
根据AIDL文件系统生成了IBookManager.java这个类,它继承了IInterface这个接口,同时他本身也是一个接口。所有在Binder中传输的接口都需要继承IInterface这个接口。
类中声明了aidl文件中声明的两个方法,这两个方法还有对应的id。
然后还生成了一个Stub内部类,这就是Binder了
属性详解:
DESCRIPTOR :Binder的唯一标识
private static final java.lang.String DESCRIPTOR = "com.example.testandroid.IBookManager";
asInterface(android.os.IBinder obj)
public static com.example.testandroid.IBookManager asInterface(android.os.IBinder obj) { if ((obj == null)) { return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin != null) && (iin instanceof com.example.testandroid.IBookManager))) { return ((com.example.testandroid.IBookManager) iin); } return new com.example.testandroid.IBookManager.Stub.Proxy(obj); }
该方法用于判断传进来的IBinder是不是就在当前进程里面,如果是的话就直接返回((com.example.testandroid.IBookManager) iin)
,不是的话就返回com.example.testandroid.IBookManager.Stub.Proxy(obj)
public android.os.IBinder asBinder():返回当前Binder
onTransact方法是在Stub的内部实现的。
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException { switch (code) { case INTERFACE_TRANSACTION: { reply.writeString(DESCRIPTOR); return true; } case TRANSACTION_getBookList: { data.enforceInterface(DESCRIPTOR); java.util.List<com.example.testandroid.Book> _result = this.getBookList(); reply.writeNoException(); reply.writeTypedList(_result); return true; } case TRANSACTION_addBook: { data.enforceInterface(DESCRIPTOR); com.example.testandroid.Book _arg0; if ((0 != data.readInt())) { _arg0 = com.example.testandroid.Book.CREATOR.createFromParcel(data); } else { _arg0 = null; } this.addBook(_arg0); reply.writeNoException(); return true; } } return super.onTransact(code, data, reply, flags); }
code:每个方法都有一个int类型的数字用来区分(后面中的swicth),也就是之前说到生成的方法ID。
data:传过来的数据,其中包含我们的参数,以及类的描述。
reply:传回的数据,我们要写入是否发生了Exception,以及返回值
flags:该方法是否有返回值 ,0表示有返回值。
调用onTransact就表示有数据传来,首先就会通过swicth判断是哪个方法,然后取出方法参数,调用本地实现的方法获取返回值,写入返回值到reply。最后,返回true,才会把数据发送出去,返回false就不会把结果返回给Activity了。这里也就是说,只有返回true,我们Proxy中才能接受从远端传回的数据。
public java.util.List<com.example.testandroid.Book> getBookList() throws android.os.RemoteException
这个方法内部实现大概是:
创建输入型Parcel对像:android.os.Parcel _data = android.os.Parcel.obtain();
创建输出型对象:android.os.Parcel _reply = android.os.Parcel.obtain();
创建返回值对像:java.util.List<com.example.testandroid.Book> _result;
然后把方法参数信息写入_data中,之后调用 mRemote.transact(Stub.TRANSACTION_getBookList, _data, _reply, 0);
发起请求。然后服务端的onTransaction方法会被调用直到这个请求被返回后 _result = _reply.createTypedArrayList(com.example.testandroid.Book.CREATOR);
获取返回结果,返回_reply中的数据return _result;
以上就是通过AIDL文件通过系统生成Binder的相关内容,当然也可以手动写一个Bineder。
- IPC基础小记 关于Binder
- IPC小记Binder连接池
- IPC基础小记
- 关于IPC,Binder,AIDL,Intent
- IPC基础概念Serializable、Parcelable、Binder
- 6.IPC 机制(四) IPC基础概念介绍 Binder
- IPC Binder
- binder IPC
- IPC Binder
- IPC小记
- 关于android IPC(AIDL、Binder、Messenger)通信
- IPC机制系列之二 IPC机制的基础概念Serializable、Parcelable以及Binder
- Binder IPC 机制
- IPC 机制Binder 剖析
- IPC binder 机制历史
- Android Binder IPC分析
- Android Binder IPC分析
- Android Binder IPC分析
- 并查集——How Many Tables
- 在Androidstudio配置svn上找不到svn.exe解决方法
- 06_判断101-200之间有多少个素数,并输出所有素数
- 数据结构(9):二叉树的遍历、构建以及显示(凹入法)
- 算法_动态规划_矩阵路径最大和
- IPC基础小记 关于Binder
- 畅通工程系列问题题解(HDU 1233 1863 1875 1879)
- c++作业3-定期存款利息计算器
- ZCCZCC Loves Codefires
- cocos2d-js常用命令
- 解决crontab不能启动(二)
- mysql导入数据乱码
- 7个你可能不认识的CSS单位:rem vh vw vmin vmax ex ch
- vagrant系列二:vagrant的配置文件vagrantfile详解