欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Binder在Java层的实现

程序员文章站 2022-06-17 22:57:49
通过Binder在native的实现可以知道Binder通信的本质就是通过Binder共享内存进行跨进程通信,所以Java层还是利用这个进行通信的,只是Client和Server内部的一些执行逻辑有变化,我们直接来看Java层是如何与Binder通信的就可以了。Java系统服务的创建过程Java系统服务在Android启动过程中由ServiceThread启动,以power系统服务为例,PowerManagerService继承自Stub类,Stub是定义在IPowerManager接口.....
通过Binder在native的实现可以知道Binder通信的本质就是通过Binder共享内存进行跨进程通信,所以Java层还是利用这个进行通信的,只是Client和Server内部的一些执行逻辑有变化,我们直接来看Java层是如何与Binder通信的就可以了。
 
Java系统服务的创建过程
 
Java系统服务在Android启动过程中由ServiceThread启动,以power系统服务为例,PowerManagerService继承自Stub类,Stub是定义在IPowerManager接口内部的抽象类,Stub继承自Binder类并实现了IPowerManager的接口,这样在创建PowerManagerServier的时候就会调用Binder的构造方法,虽然这是Java层的Binder,但是从名字就知道跟Binder驱动通信就是它做的。
Binder在Java层的实现
、上图是从Java的PowerManagerService到Native的BBinder的引用过程,这里看一下native的JavaBBinder,看名字就知道它和BBinder还有Java有关,它继承BBinder,通过BBinder就能跟Binder驱动通信,它里面还保存的Java层Binder的引用,这里Java层Binder的实例是PowerManagerService。在native层,与Binder通信还是BBinder做的,JavaBBinder就是一个具备与java层通信能力的BBinder,在Java层是由Binder和Native的JavaBBinder进行通信,我们的服务继承了Binder,也继承了与JavaBBinder通信的能力,这样就通过Native的JavaBBinder和Java的Binder将服务与Binder关联了起来。
 
注册到ServiceManager
 
服务创建完就要注册到ServiceManager,在Native的Binder中是用一个持有BpBinder(0)引用的BpServiceManager做的,Java其实也是用的BpBinder(0),但是使用方式和Native层肯定是有区别的,这里是将Native的BpBinder(0)存入Java层BinderProxy对象中,然后将BinderProxy存入ServiceManagerProxy中, ServiceManagerProxy实现了IServiceManager接口,可以当做ServiceManager使用,并且持有BinderProxy,可以和Binder通信。因为通信的远离在Native中都已经知道了,我觉得了解一下各个模块层级的引用关系就知道整个架构了,如果对细节深究看源码就可以了。
Binder在Java层的实现
addService也是通过BpBinder(0)与ServiceManager通信的。
 
Client获取服务代理
 
在Service注册的时候知道java层与Binder通信是BinderProxy做的,那么Client获取服务代理也就是通过ServiceManager的BinderProxy,这里得到服务的BinderProxy后需要将其封装成接口给Client使用,这里和ServiceManager是有区别的。
Binder在Java层的实现
从图上看,整体结构关系都是一样的,只是普通服务的Proxy不像ServiceManagerProxy那样拥有姓名,名字都是Proxy,只是不同服务的Proxy是定义在在不同服务的内部类Stub中的,同时IPowerManager是不会公开在SDK中的,最终Client得到的是PowerManager,它通过IPowerManager来实现与PowerService通信。
将上面的两张图合在一起就是整体的通信过程。
Binder在Java层的实现
如果了解了Binder的通信的实现原理,在通过这张图了解引用关系,就很容易理解Java层是如何利用Binder进行跨进程通信的。
 
AIDL

Android提供了AIDL(Android Interfce Definition Language)来定义C/S体系中的接口,当我们定义好AIDL接口后,AIDL工具会根据这个接口给我们自动创建好对应的Java文件。
以IPowerManager.aidl为例:
interface IPowerManager{
      boolean isScreenOn();
}

AIDL工具会将其转化为IPowerManager.java:

public interface IPowerManager extends android.os.IInterface{
          
           public static abstract class Stub extends android.os.Binder   implements android.os.IPowerManager{

                      public static android.os.IPowerManager asInterface(android.os.IBinder obj){
                                ........
                                return new android.os.IPowerManager.Stub.Proxy(obj);
                       }

                       public boolean  onTransact(int code,android.os.Parcel data,android.os.Parcel reply,int flags){
                                  switch(code){
                                            case TRANSACTION_isScreenOn:{
                                                    boolean _result = this.isScreenOn();
                                                    reply.writeInt(result);
                                            }
                                  }
                       }

                       private static class Proxy implements android.os.IPowerManager{
                                   private android.os.IBinder mRemote;//BinderProxy
                                   public boolean isScreenOn{
                                           mRemote.transact(Stub.TRANSACTION_isScreenOn,data,reply,0);
                                           return reply.readInt();
                                   }
                       }
           }

}

上面的Java文件省略了很多内容,我们可以看到会帮我们创建Stub和Proxy,在Stub的asInterface中返回Proxy,在Proxy中调用BinderProxy通信并返回结果,Server端只要继承Stub,实现IPowerManager中定义的方法即可。

 

本文地址:https://blog.csdn.net/wjtzc1990/article/details/107421944

相关标签: android总结