我是靠谱客的博主 激动摩托,最近开发中收集的这篇文章主要介绍android中Binder的深入理解,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

开始之前我们先来讲下Binder的定义:

  Binder实体对象:Binder实体对象就是Binder服务的提供者。一个提供Binder服务的类必须继承BBinder

  Binder引用对象:Binder引用对象是Binder实体对象在客户端进程的代表,每个引用对象的类型多少BpBinder类,同时可以用名称“BpBinder对象”来代替“Binder引用对象”

 Binder代理对象:代理对象也叫接口对象,它主要是为客户端的上层应用提供接口服务,从IInterface(注意是IInterface不是Interface),它实现了Binder服务的函数接口

IBinder对象:BBinder和BpBinder类都是从IBinder类中继承而来。很多场合,不需要刻意地区分实体对象和引用对象,可以使用“IBinder对象”来统一称呼



Binder的架构:

    Binder驱动:Binder的核心,实现各种Binder的底层操作

   ServiceManager:提供Binder的名称到引用对象的转换服务

  服务端:Binder服务的提供者

  客户端:Binder服务的使用者

ServiceManager:

     1.Binder框架硬性规定0代表ServiceManager

     2.它里面有一张表,里面规定了能够注册服务的进程的用户ID,以及进程能够注册的服务的名称

    3.他能通过这张表来控制进程的注册请求


java中如何使用Binder?

  1.编写AIDL文件

  2编写Service

   3.在清单文件中加入服务的声明

   4.调用bindService


使用注意点:

    1.写的Service类必须重载底层的onBind()方法,其中返回Binder服务的实体对象。例如IExampleService.Stub类是真正的Binder服务类,它是通过前面的aidl文件自动生成的。

   2.应用中的onServiceConnect()中最后一个参数为IBinder,它实际上是个引用对象,但是应用需要的是Binder的代理对象,因此使用前需要把引用对象转变成代理对象:

      IExample service = IExampleService.Stub.asInterface(service);


补充:

    asInterface()的作用? 它是把Binder引用对象转变为代理对象

    Java中的接口类都是通过AIDL自动生成

     流程:1.先通过queryLocalInterface()方法的返回值来判断传入的参数是否是服务端的Binder类

                2.如果是就返回参数obj

                 3.否则就认为obj是Binder的引用对象,这时需要新创建一个代理对象

注意:如 com.example.test.IExampleService.Stub.proxy(..)就是一个AIDL自动生成的代理对象


Binder的实现原理:

   Binder是面向对象的,面向对象的最大问题是跨进程管理对象的生命周期,服务中的实体对象死亡后,客户进程中的引用对象也需要删除,而且这个过程需要自动完成而不能由上层的客户程序协助完成。

   如何实现?

      1.客户进程中需要集中管理本进程中所以Binder引用对象,并负责他们的创建和释放。ProcessState类的作用正是管理进程中引用对象

       2.为了系统中所以引用对象与实体对象能相互关联,Binder在驱动中还建立了一张所用进程中的引用对象和实体对象的关联表。

      3.Binder又必须保证用户进程中实体对象或引用对象和驱动的数据一致为了这个目标,Binder定义了自己的引用计数机制,而且这种机制是跨进程的。


问题2:参数传递如何实现?

             一般的对象作为参数传递没有太大的问题,只需要序列化和反序列化就能实现,但是,Binder对象作为参数传递的时候。就会面理实体对象和引用对象相互转化的问题,为了让上层引用使用方便,这种转换也是在驱动中完成。


Binder和普通IPC的不同点?

     普通IPC传送数据时,需要经历两次复制过程,一次是从调用者的数据缓冲区复制到内核的缓冲区,第二次是从内核的缓冲区复制到接收进程的读缓冲区

     Binder为每个进程创建了一个缓存区,这个缓存区在内核和用户进程间共享,传输数据到驱动只需要从发送进程的用户空间缓冲区复制到目标进程在驱动的缓冲区,但是目标进程从驱动中读取数据不再需要从内核空间复制到用户空间了,而直接从内核共享的缓冲区中读取,这样减少一次数据复制进程。





  Binder服务分成两种:实名服务和匿名服务

    区别:实名服务能够通过ServiceManager查询到

    Android中的实名服务都是系统提供的如ActivityManagerService,PowerManagerService,WidnowManagerService

 匿名服务:普通应用开发的Binder服务,只能是匿名服务


问题:如果匿名服务不能通过ServiceManager查询到,使用者通过什么方式才得到他的应用对象?

     通过Binder。匿名服务经常使用的场景:客户端进程回调服务进程中的函数。

       过程:客户端和服务端通过Binder链接后,服务端把本进程中创建的匿名服务的实体对象作为函数传递到客户端。驱动会在中间把实体对象作为函数参数传递到客户端。驱动会在中间把实体对象转换成引用对象,这样客户进程就得到服务进程创建的Binder服务的引用对象,然后就能回调服务进程中Binder服务的函数


 在java层Android还提供通过组件Service的方式来包装和使用匿名服务



  Android还通过FrameWorkd提供了一种启动Java匿名Binder服务的方法。

  1.某个应用通过调用bindService()方法发出一个Intent,Framwork根据Intent找到对应的组件Service并启动它,包在Service组件中的Binder服务也将同时创建出来。

  2.随后Framework会把服务中的IBinder对象通过ConnectionManager的回调方法onServiceConntectd()传回到应用。

  3.应用就是得到匿名Binder服务的引用对象,就可以使用组件中Service中匿名Binder服务了



最后

以上就是激动摩托为你收集整理的android中Binder的深入理解的全部内容,希望文章能够帮你解决android中Binder的深入理解所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部