当前位置: 首页 > news >正文

各大高校的校园网站建设wordpress主页空白

各大高校的校园网站建设,wordpress主页空白,域客士单页网站,中国建筑公司网站读完本文你将了解#xff1a; IBinderBinderBinder 通信机制 Binder 驱动Service ManagerBinder 机制跨进程通信流程 Binder 机制的优点总结Thanks 上篇文章 Android 进阶7#xff1a;进程通信之 AIDL 中我们虽然跨进程通信成功#xff0c;但是还是有很多疑问的#xff0…读完本文你将了解 IBinderBinderBinder 通信机制 Binder 驱动Service ManagerBinder 机制跨进程通信流程 Binder 机制的优点总结Thanks 上篇文章 Android 进阶7进程通信之 AIDL 中我们虽然跨进程通信成功但是还是有很多疑问的比如 AIDL 帮我们做了什么为什么要这么写什么是 Binder 知其然还要知其所以然一切都要从 Binder 讲起。 IBinder Binder 继承自 IBinder所以我们先来了解下它。 public class Binder implements IBinder {...} public interface IBinder {...} IBinder 是一个接口它代表了一种跨进程传输的能力。只要实现了这个接口就能将这个对象进行跨进程传递。 IBinder 是高性能、轻量级远程调用机制的核心部分它定义了远程操作对象的基本接口。 这些方法中最关键的一个是 transact(): public boolean transact(int code, Parcel data, Parcel reply, int flags)throws RemoteException; 与它对应的是 Binder.onTransact() protected boolean onTransact(int code, Parcel data, Parcel reply,int flags) throws RemoteException {...} 可以看到这两个方法非常相似介绍一下方法中的各个参数 code要执行的动作类似 Handler 的 msg.whatIBinder 中定义了以下几个 code PING_TRANSACTION表示要调用 pingBinder() 方法DUMP_TRANSACTION表示要获取 Binder 内部状态SHELL_COMMAND_TRANSACTION执行一个 shell 命令INTERFACE_TRANSACTION询问被调用方的接口描述符号TWEET_TRANSACTIONLIKE_TRANSACTION如果我们需要自定义 codecode 的值范围需要在 FIRST_CALL_TRANSACTION(0x00000001) 和 LAST_CALL_TRANSACTION(0x00ffffff) 之间data, reply传入的参数和返回的值flags表示是否需要阻塞等待返回值有两个值 0FLAG_ONEWAY (0x00000001)表示 Client 的 transact() 是单向调用执行后立即返回 ①经常的场景是我们调用 IBinder.transact() 给一个 IBinder 对象发送请求然后经过 Binder Binder.onTransact() 得到调用接着远程操作的目标得到对应的调用。 这个过程不仅在同一进程中可以进行在跨进程IPC间也可以完成。 IBinder.transact() 方法是同步的它被调用后一直到 Binder.onTransact() 调用完成后才返回。 ②通过 IBinder.transact() 方法传输的数据被保存为一个 Parcel 对象Parcel 中保存了数据以及描述数据的元数据元数据在缓存区中保持了 IBinder 对象的引用这样不同进程都可以访问同一个数据。 因此在一个 IBinder 对象写入 Parcel 对象然后发送到另一个进程时另外那进程将这个 IBinder 对象发送回去时原本进程接收到的 IBinder 对象和开始发送出去的是同一个引用。 在跨进程传输后引用没有改变这是非常关键的一点这就使得 IBinder/Binder 对象在跨进程通信时可以作为唯一的标识比如作为 token 什么的。 ③系统在每个进程中都有一个处理事物的线程池这些线程用于调度其他进程对当前进程的跨进程访问。 比如说进程 A 对进程 B 发起 IPC 时A 中调用 transact() 的线程会阻塞。B 中的事物线程池收到 A 的 IPC调用目标对象的 Binder.onTransact() 方法然后返回带结果的 Parcel。一旦接收到结果A 中阻塞的线程得以继续执行。 这个过程和线程通信非常相似吧。 ④Binder 机制还支持进程间的递归调用。 比如进程 A 向进程 B 发起 IPC而进程 B 在其 Binder.onTransact() 中又用 transact() 向进程 A 发起 IPC那么进程 A 在等待它发出的调用返回的同时也会响应 B 的调用对调用的对象执行 Binder.onTransact() 方法。 这种机制可以让我们觉得到跨进程的调用与进程内的调用没什么区别这是非常重要的。 ⑤在跨进程通信时我们常常想要知道另外进程是否可用IBinder 提供了三个检查的方法 transact() 当你调用的 IBinder 所在进程不存在时会抛出 RemoteException 异常pingBinder() 当远程进程不存在时该方法返回 falselinkToDeath() 这个方法可以向 IBinder 中注册一个 IBinder.DeathRecipient它将在 IBinder 所在的进程退出时被调用 /*** 检查远程 Binder 对象是否存在* * 当不存在时返回 false*/ public boolean pingBinder(); /*** 注册一个 Binder 销毁的监听如果一个 Binder 被销毁通常是它所在的进程被关闭会回调 DeathRecipient 的 BinderDied 方法* 注意只会监听远程的 Binder本地 Binder 一般不会销毁除非当前进程退出* * 如果要注册的 Binder 进程已经销毁就抛出 RemoteException */ public void linkToDeath(DeathRecipient recipient, int flags)throws RemoteException;/*** linkToDeath 注册监听回调的接口*/ public interface DeathRecipient {public void binderDied(); } Binder 官方文档中建议 日常开发中一般不需要我们再实现 IBinder直接使用系统提供的 Binder 即可。 Binder 实现了 IBinder 定义的操作它是 Android IPC 的基础平常接触到的各种 ManagerActivityManager, ServiceManager 等以及绑定 Service 时都在使用它进行跨进程操作。 它的存在不会影响一个应用的生命周期只要创建它的进程在运行它就一直可用。 通常我们需要在顶级的组件Service, Activity, ContentProvider中使用它这样系统才知道你的进程应该一直被保留。 下面介绍 Binder 的几个关键方法 实现 IBinder 的 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);}boolean r onTransact(code, data, reply, flags);if (reply ! null) {reply.setDataPosition(0);}return r; } 可以看到这个方法就是调用 onTransact() 然后将返回的结果再返回回去。 接着看看 onTransact() 方法 protected boolean onTransact(int code, Parcel data, Parcel reply,int flags) throws RemoteException {if (code INTERFACE_TRANSACTION) { //获取接口描述reply.writeString(getInterfaceDescriptor());return true;} else if (code DUMP_TRANSACTION) { //获取当前状态ParcelFileDescriptor fd data.readFileDescriptor();String[] args data.readStringArray();if (fd ! null) {try {dump(fd.getFileDescriptor(), args);} finally {IoUtils.closeQuietly(fd);}}// Write the StrictMode header.if (reply ! null) {reply.writeNoException();} else {StrictMode.clearGatheredViolations();}return true;} else if (code SHELL_COMMAND_TRANSACTION) { //执行 shell 脚本ParcelFileDescriptor in data.readFileDescriptor();ParcelFileDescriptor out data.readFileDescriptor();ParcelFileDescriptor err data.readFileDescriptor();String[] args data.readStringArray();ResultReceiver resultReceiver ResultReceiver.CREATOR.createFromParcel(data);try {if (out ! null) {shellCommand(in ! null ? in.getFileDescriptor() : null,out.getFileDescriptor(),err ! null ? err.getFileDescriptor() : out.getFileDescriptor(),args, resultReceiver);}} finally {IoUtils.closeQuietly(in);IoUtils.closeQuietly(out);IoUtils.closeQuietly(err);// Write the StrictMode header.if (reply ! null) {reply.writeNoException();} else {StrictMode.clearGatheredViolations();}}return true;}return false; } 也没看出什么特别的系统的 Binder.onTransact() 方法只定义了系统要进行的操作我们如果创建自己的 Binder 时就需要重写这个方法根据 code 对传入的参数 data 做相应的处理然后写入 reply这样就能返回操作后的数据。 另外一个关键的方法 attachInterface public void attachInterface(IInterface owner, String descriptor) {mOwner owner;mDescriptor descriptor; } /* mObject is used by native code, do not remove or rename */ private long mObject; private IInterface mOwner; private String mDescriptor; 这个方法的作用是将一个描述符、特定的 IInterface 与当前 Binder 绑定起来这样后续调用 queryLocalInterface 就可以拿到这个 IInterface那 IInterface 又是什么呢 public interface IInterface {/*** Retrieve the Binder object associated with this interface.* You must use this instead of a plain cast, so that proxy objects* can return the correct result.*/public IBinder asBinder(); } 其实看名字就可以大概猜出来IInterface 应该就是进程间通信定义的通用接口我们通过定义接口然后再服务端实现接口、客户端调用接口就可以实现跨进程通信。 IInterface 里只定义了一个 asBinder() 方法这个方法可以返回当前接口关联的 Binder 对象。 Binder 通信机制 上面介绍了 Binder 类以及相关的方法但是这只是 Binder 机制的最基础部分。 我们平常看的文章或者面试时说的 Binder 其实是范围更大的整个 “Binder 消息通信机制”。 借用老罗的 Android进程间通信IPC机制Binder简要介绍和学习计划 中对 Binder 通信机制的介绍 在 Android 系统的 Binder 机制中由四个组件组成分别是 ClientServerServiceManager提供辅助管理 Server 的功能Binder 驱动程序整个机制的核心 Binder 驱动 驱动程序一般指的是设备驱动程序Device Driver是一种可以使计算机和设备通信的特殊程序。相当于硬件的接口操作系统只有通过这个接口才能控制硬件设备的工作。 我们知道在 Linux 系统中内存空间分为两部分 用户空间运行着应用程序内核空间运行着系统内核和驱动 用户空间中的进程无法直接访问内核空间需要通过上图中的 System Call Interface 系统调用接口通过这个统一入口所有资源访问都是在内核的控制下执行这样可以避免用户程序对系统资源的越权访问从而保障了系统的安全和稳定。 同样的用户空间中的进程直接也不可以直接访问数据需要通过内核空间进行中转。 在 Binder 机制中由 Binder 驱动负责完成这个中转操作主要过程如下 当 Client 向 Server 发起 IPC 请求时Client 会先将请求数据从用户空间拷贝到内核空间数据被拷贝到内核空间之后驱动程序将内核空间中的数据拷贝到 Server 位于用户空间的缓存中 这样就成功的将 Client 进程中的请求数据传递到了 Server 进程中。 实际上Binder 驱动是整个 Binder 机制的核心。除了实现数据传输之外Binder 驱动还是实现线程控制(通过中断等待队列实现线程的等待/唤醒)以及 UID/PID 等安全机制的保证。 http://wangkuiwu.github.io/2014/09/01/Binder-Introduce/ Service Manager ServiceManager 运行在用户空间它负责管理 Service 注册与查询。 看下 ServiceManager 的代码 public final class ServiceManager {private static final String TAG ServiceManager;private static IServiceManager sServiceManager;private static HashMapString, IBinder sCache new HashMapString, IBinder();private static IServiceManager getIServiceManager() {if (sServiceManager ! null) {return sServiceManager;}// Find the service managersServiceManager ServiceManagerNative.asInterface(BinderInternal.getContextObject());return sServiceManager;}/*** 根据 Service 名称获取 Service*/public static IBinder getService(String name) {try {IBinder service sCache.get(name);if (service ! null) {return service;} else {//如果不存在就去 IServiceManager 中找这时可能会阻塞return getIServiceManager().getService(name);}} catch (RemoteException e) {Log.e(TAG, error in getService, e);}return null;}/*** 添加一个 Service 到 Manager 中*/public static void addService(String name, IBinder service) {try {getIServiceManager().addService(name, service, false);} catch (RemoteException e) {Log.e(TAG, error in addService, e);}}/*** 添加一个 Service 到 Manager 中,如果 allowIsolated 为 true 表示运行在沙盒中的进程也可以访问这个 Service*/public static void addService(String name, IBinder service, boolean allowIsolated) {try {getIServiceManager().addService(name, service, allowIsolated);} catch (RemoteException e) {Log.e(TAG, error in addService, e);}}/*** Retrieve an existing service called a name from the* service manager. Non-blocking.*/public static IBinder checkService(String name) {try {IBinder service sCache.get(name);if (service ! null) {return service;} else {return getIServiceManager().checkService(name);}} catch (RemoteException e) {Log.e(TAG, error in checkService, e);return null;}}/*** 获取 Service 列表*/public static String[] listServices() {try {return getIServiceManager().listServices();} catch (RemoteException e) {Log.e(TAG, error in listServices, e);return null;}}/*** 当前进程首次被 activity manager 创建时调用这个方法 */public static void initServiceCache(MapString, IBinder cache) {if (sCache.size() ! 0) {throw new IllegalStateException(setServiceCache may only be called once);}sCache.putAll(cache);} } 可以看到 ServiceManager 提供了 Service 的添加和查询其中主要操作都是通过 IServiceManager它是何方神圣 public interface IServiceManager extends IInterface {/*** 获取一个 Service不存在就会阻塞几秒*/public IBinder getService(String name) throws RemoteException;/*** 不阻塞的获取 Service*/public IBinder checkService(String name) throws RemoteException;public void addService(String name, IBinder service, boolean allowIsolated)throws RemoteException;public String[] listServices() throws RemoteException;/*** 为 Service Manager 添加权限具体作用暂不追究*/public void setPermissionController(IPermissionController controller)throws RemoteException;static final String descriptor android.os.IServiceManager;//定义了一些用于调用 transact() 方法的 codeint GET_SERVICE_TRANSACTION IBinder.FIRST_CALL_TRANSACTION;int CHECK_SERVICE_TRANSACTION IBinder.FIRST_CALL_TRANSACTION1;int ADD_SERVICE_TRANSACTION IBinder.FIRST_CALL_TRANSACTION2;int LIST_SERVICES_TRANSACTION IBinder.FIRST_CALL_TRANSACTION3;int CHECK_SERVICES_TRANSACTION IBinder.FIRST_CALL_TRANSACTION4;int SET_PERMISSION_CONTROLLER_TRANSACTION IBinder.FIRST_CALL_TRANSACTION5; } 可以看到 IServiceManager 是一个接口它定义了管理 Service 的一些方法同时继承了 IInterface。最常见的实现是 BnServiceManager.getDefault()。 Binder 机制跨进程通信流程 上面两节简单介绍了 Binder 机制中非常重要的两部分ServiceManager 和 Binder 驱动。 在 Binder 机制的四个部分中 Client、Server 和 ServiceManager 运行在用户空间Binder 驱动程序运行内核空间。 Binder 就是一种把这四个组件粘合在一起的粘结剂。 这个流程是如何进行的呢 借用 Android Binder机制(一) Binder的设计和框架 的图片 上图简单介绍节选自 http://wangkuiwu.github.io/2014/09/01/Binder-Introduce/ Binder实体 Binder 实体实际上是内核中 binder_node 结构体的对象它的作用是在内核中保存 Server 和ServiceManager 的信息(例如Binder 实体中保存了 Server 对象在用户空间的地址)Binder 实体是 Server 在 Binder 驱动中的存在形式内核通过 Binder 实体可以找到用户空间的Server对象在上图中Server 和 ServiceManager 在 Binder 驱动中都对应的存在一个 Binder 实体Binder 引用 Binder引用实际上是内核中 binder_ref 结构体的对象是某一个 Binder 实体的引用通过Binder 引用可以在内核中找到对应的 Binder 实体如果将 Server 看作是 Binder 实体的话那么 Client 就好比 Binder 引用Client 通过保存一个Server 对象的 Binder 引用再通过该 Binder 引用在内核中找到对应的 Binder 实体进而找到Server 对象然后将通信内容发送给 Server 对象远程服务 本地服务的代理通过调用远程服务可以间接调用本地服务 1.Client、Server 和 ServiceManager 处于用户空间的不同进程。 2.Binder 实体和 Binder 引用都是内核(即 Binder 驱动)中的数据结构。 它们的关系如下 每一个 Server 在内核中就表现为一个 Binder 实体而每一个 Client 则表现为一个 Binder 引用。这样每个 Binder 引用都对应一个 Binder 实体而每个 Binder 实体则可以多个 Binder 引用。 Binder 跨进程通讯流程主要为如下 4 步 ServiceManager 初始化 当该应用程序启动时ServiceManager 会和 Binder 驱动进行通信告诉 Binder 驱动它是服务管理者Binder 驱动新建 ServiceManager 对应的 Binder 实体Server 向 ServiceManager 注册自己 Server 向 Binder 驱动发起注册请求Binder 为它创建 Binder 实体然后如果 ServiceManager 中没有这个 Server 时就添加 Server 名称与 Binder 引用到它的 Binder 引用表Client 获取远程服务 Client 首先会向 Binder 驱动发起获取服务的请求传递要获取的服务名称Binder 驱动将该请求转发给 ServiceManager 进程ServiceManager 查找到 Client 需要的 Server 对应的 Binder 实体的 Binder 引用信息然后通过 Binder 驱动反馈给 ClientClient 收到 Server 对应的 Binder 引用后会创建一个 Server 对应的远程服务即 Server 在当前进程的代理Client 通过代理调用 Server Client 调用远程服务远程服务收到 Client 请求之后会和 Binder 驱动通信因为远程服务中有 Server 的 Binder 引用信息因此驱动就能轻易的找到对应的 Server进而将Client 的请求内容发送 Server Binder 机制的优点 对比 Linux 上的其他进程通信方式管道/消息队列/共享内存/信号量/SocketBinder 机制的优点有以下几点 高效简单 通过驱动在内核空间拷贝数据不需要额外的同步处理对比 Socket 等传输效率高安全 Binder 机制为每个进程分配了 UID/PID 来作为鉴别身份的标示并且在 Binder 通信时会根据UID/PID 进行有效性检测Client/Server 架构 这种架构使得通讯更为简单 总结 Binder 机制的学习过程是痛苦的 T.T即使光看 Java 层也费了不少功夫这可能是由于我实战中没有遇到光看源码和抽象概念掌握太慢的原因吧。 本文简单介绍了 Binder 机制参考了很多优秀的文章真佩服他们 借用《Android 开发艺术探索》对 Binder 的概括 从代码角度来看Binder 是一个类实现了 IBinder 接口 从来源看Binder 来自于 OpenBinder,是 Android IPC 机制中的一种Binder 还可以理解成一个虚拟物理设备设备驱动是dev/binder 从 Framework 层看Binder 是 Service Manager 连接各种Manager(ActivityManager,PackageManager…) 和相应Service (ActivityManagerService, PackageManagerService…) 的桥梁 从客户端看Binder 是客户端服务器通讯的媒介 在对 Binder 有了一定理解后下篇文章我们就去看看 AIDL 帮我们做了什么。 Thanks 《Android 开发艺术探索》 https://developer.android.com/reference/android/os/IBinder.html http://blog.csdn.net/luoshengyang/article/details/6618363 http://blog.csdn.net/luoshengyang/article/details/6642463 http://weishu.me/2016/01/12/binder-index-for-newer/ http://wangkuiwu.github.io/2014/09/01/Binder-Introduce/ http://blog.csdn.net/u010132993/article/details/72582655
http://www.sczhlp.com/news/214713/

相关文章:

  • 手机网站建设公司报价免费网站如何做推广方案
  • 加快信用网站建设网站title标签内容怎么设置
  • 如何提升网站收录广州新冠新增最新消息
  • 深圳网站策划南宁seo管理
  • 私人订制网站有哪些品牌型网站制作价格
  • 佛山网站建设通州建设网站
  • 个人工作室如何做网站宜宾网站建设略奥网络
  • 网站百度收录很多h5百度百科
  • 做网站的业务逻辑网站怎么免费建站
  • 罗湖装修公司网站建设专业 网站设计
  • 合肥建设集团招聘信息网站网页制作模板端午节
  • 哪些网站可以兼职做设计武城网站建设价格
  • 响应式网站建设开发公司网站建设技术文章
  • php网站开发技术前景百度h5制作软件下载
  • mysql数据库查询参考
  • 如今做那些网站致富怎么用php做网站
  • 电子商务网站平台建设费用做网站建设个体经营小微企业
  • 手机版网站模板 免费下载计算机前端培训多少钱
  • 200元网站建设广州企业100强
  • 网站制作的软件北京王府井半岛酒店
  • 门户网站开发费需入无形资产wordpress菜单设置图标
  • 广西兴业县建设局网站wordpress字不能
  • 大型网站tag标签 索引重庆网站建设仿站
  • 门户网站建站目标网站建设方案概念
  • 视频网站怎么做外链北京智能网站建设平台
  • 做网站站长临安市住房和建设局网站
  • 建立网站需要注册公司吗wordpress编辑器修改
  • 上海兴业建设有限公司网站wordpress 博客改成文章
  • Python理论题目集
  • 视觉和语言 国防科大清华城市空间无人机导航推理!GeoNav:赋予多模态大模型地理空间推理能力,实现语言指令导向的空中目标导航 - MKT