Binder通信与AIDL

    

系统服务依赖的是Binder构架。

 

Binder和BinderProxy直接继承IBinder。

 

通信:服务Proxy(如:ActivityManagerService)通过BinderProxy,再通过BpBinder,再将请求传到Binder驱动。Binder驱动通过ServiceManager得到注册的IBinder对应的JavaBBinder,再层层上到java层的真正服务对象。这样可以实现跨进程通信。

 

在以上的构架基础上,ADIL为我们简化了整个通信的搭建过程。

首先,你要定义一个aidl格式的文件,如:

package com.udnderstanding.samples;

interface ImyServer{

   int foo(String str);

}

这样就定义了一个名为IMyServer的Binder服务,并提供了一个可以跨Binder调用的接口foo()。

一个AIDL文件将被aidl工具解析成三个产物:

1.IMyServer接口:它仅仅用来在Java 中声明IMyServer.aidl中所声明的接口。

2.IMyServer.Stub类:这个继承自Binder类的抽象类实现了Bn端与Binder通信相关的代码

3.IMyServer.Stub.Proxy类。这个类实现了Bp端与Binder通信相关的代码。

在完成爱的了解析后,为了实现一个Bn端,开发者需要继承IMyServer.Stub类并实现其抽象方法。

每个MyServer实例都具有了作为Bn端的能力。

典型用法:

1.将MyServer类的实例通过ServiceManager.addService(String name, IBinder service)将其注册为一个系统服务。

2.在一个Android标准Service的onBind()方法中将其作为返回值使之可以被其他进程访问

3.通过binder调用将其传递给另外一个进程,使之成为一个跨进程的回调对象。

但是殊途同归,在Bp端所在进程中,一旦获取了IMyServer的BinderProxy(通过ServiceManager.geService()、onSrviceConnected()、或者其他方式),就可以通过如下方式获得一个IMyServer.Proxy:

//就是最终需要获得com.understanding.samples.IMyServer.Stub.Proxy,asInterface()返回就是这个类型

IMyServer remote = IMyServer.Stub.asInterface(binderProxy);

remote.foo("Hello AIDL");

 

 

 

下面是aidl工具自动解析成的文件。

public interface IMyServer extends android.os.IInterface{

    //自动生成一个内部类

    public static abstract class Stub extends android.os.Binder implements com.understanding.samples.IMyServer{

 

/********code:对应不同的方法,表示proxy所需调用的方法。

data:从proxy打包传过来的参数

在proxy发出请求后,最终会调用Stub的子类的onTransact()方法,而onTransact()中会调用foo(),所以子类需实现foo()

*/

          public boolena onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags)

           throws android.os.RemoteException{

              switch(code){

                   ......

               case TRANSACTION_foo:{

                   ......//从data中读取参数_arg0

            //Stub类的子类需要实现foo()方法

                  int _result = this.foo(_arg0);

                  ......//向reply中写入_result

                  return true;

                    }

               }

        return super.onTransact(code, data, reply, flags);

        }

    

 

//调用了Bp端的foo对应会调用Bn端的foo。Bp端的foo()的逻辑是固定的,就是将传过来的参数打包传Bn端。

      private static class Proxy implements com.understanding.samples.IMyServer{

            ......//Proxy类的其他实现

           public int foo(java.lang.String str)

                 throws android.os.RemoteException{

              android.os.Parcel _data = android.os.Parcel.obtain();

             android.os.Parcel _reply = android.os.Parcel.obtain();

             int _result;

              try{

                  ......//将参数str写入_data

           //mRemot就是指向IMyServer Bn端的BinderProxy;可能会阻塞等待返回结果

         

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值