Android AIDL

Android AIDL

下面是三个类Post.class(用上面Parcelable的Post作为实例,主要是得实现Parcelable序列化),Post.aidl和IPostManager.aidl

//Post.aidl

package com.gss.aidl

prarcelable Post;

//IPostManager.aidl

package com.gss.aidl

import com.gss.aidl.Post

interface IPostManager{

    List<Post> getBookList();

    void addBook(in Book book);

}

注意每个类所在位置,post类和post.aidl必须同包名,同名字,分别在aidl和java目录下。

然后就是一键生成ADIL的代码,系统会为我们生成IPostManager.java这个类,他继承了IInterface接口,所有binder传输接口都要继承

IInterface接口。声明了IPostManager的方法,生成id标识这两个方法。接着声明内部类Stub,这就是一个binder类,当服务端和客户端处于同一个进程,方法调用不会走跨进程的transact过程,当两者不一样的时候,就需要了。这个逻辑,由Stub的内部代理类Proxy来完成。

下面介绍Stub和Proxy类的方法含义:

/*

* This file is auto-generated.  DO NOT MODIFY.

*/

package com.gss.aidl;

public interface IPostManager extends android.os.IInterface

{

  /** Default implementation for IPostManager. */

  public static class Default implements com.gss.aidl.IPostManager

  {

    @Override public java.util.List<com.gss.aidl.Post> getBookList() throws android.os.RemoteException

    {

      return null;

    }

    @Override public void addBook(com.gss.aidl.Post book) throws android.os.RemoteException

    {

    }

    @Override public com.gss.aidl.Post getBook() throws android.os.RemoteException

    {

      return null;

    }

    @Override

    public android.os.IBinder asBinder() {

      return null;

    }

  }

  /** Local-side IPC implementation stub class. */

  public static abstract class Stub extends android.os.Binder implements com.gss.aidl.IPostManager

  {

    private static final java.lang.String DESCRIPTOR = "com.gss.aidl.IPostManager";

    /** Construct the stub at attach it to the interface. */

    public Stub()

    {

      this.attachInterface(this, DESCRIPTOR);

    }

    /**

     * Cast an IBinder object into an com.gss.aidl.IPostManager interface,

     * generating a proxy if needed.

     */

    public static com.gss.aidl.IPostManager asInterface(android.os.IBinder obj)

    {

      if ((obj==null)) {

        return null;

      }

      android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);

      if (((iin!=null)&&(iin instanceof com.gss.aidl.IPostManager))) {

        return ((com.gss.aidl.IPostManager)iin);

      }

      return new com.gss.aidl.IPostManager.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

    {

      java.lang.String descriptor = DESCRIPTOR;

      switch (code)

      {

        case INTERFACE_TRANSACTION:

        {

          reply.writeString(descriptor);

          return true;

        }

        case TRANSACTION_getBookList:

        {

          data.enforceInterface(descriptor);

          java.util.List<com.gss.aidl.Post> _result = this.getBookList();

          reply.writeNoException();

          reply.writeTypedList(_result);

          return true;

        }

        case TRANSACTION_addBook:

        {

          data.enforceInterface(descriptor);

          com.gss.aidl.Post _arg0;

          if ((0!=data.readInt())) {

            _arg0 = com.gss.aidl.Post.CREATOR.createFromParcel(data);

          }

          else {

            _arg0 = null;

          }

          this.addBook(_arg0);

          reply.writeNoException();

          return true;

        }

        case TRANSACTION_getBook:

        {

          data.enforceInterface(descriptor);

          com.gss.aidl.Post _result = this.getBook();

          reply.writeNoException();

          if ((_result!=null)) {

            reply.writeInt(1);

            _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);

          }

          else {

            reply.writeInt(0);

          }

          return true;

        }

        default:

        {

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

        }

      }

    }

    private static class Proxy implements com.gss.aidl.IPostManager

    {

      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.gss.aidl.Post> 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.gss.aidl.Post> _result;

        try {

          _data.writeInterfaceToken(DESCRIPTOR);

          boolean _status = mRemote.transact(Stub.TRANSACTION_getBookList, _data, _reply, 0);

          if (!_status && getDefaultImpl() != null) {

            return getDefaultImpl().getBookList();

          }

          _reply.readException();

          _result = _reply.createTypedArrayList(com.gss.aidl.Post.CREATOR);

        }

        finally {

          _reply.recycle();

          _data.recycle();

        }

        return _result;

      }

      @Override public void addBook(com.gss.aidl.Post 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);

          }

          boolean _status = mRemote.transact(Stub.TRANSACTION_addBook, _data, _reply, 0);

          if (!_status && getDefaultImpl() != null) {

            getDefaultImpl().addBook(book);

            return;

          }

          _reply.readException();

        }

        finally {

          _reply.recycle();

          _data.recycle();

        }

      }

      @Override public com.gss.aidl.Post getBook() throws android.os.RemoteException

      {

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

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

        com.gss.aidl.Post _result;

        try {

          _data.writeInterfaceToken(DESCRIPTOR);

          boolean _status = mRemote.transact(Stub.TRANSACTION_getBook, _data, _reply, 0);

          if (!_status && getDefaultImpl() != null) {

            return getDefaultImpl().getBook();

          }

          _reply.readException();

          if ((0!=_reply.readInt())) {

            _result = com.gss.aidl.Post.CREATOR.createFromParcel(_reply);

          }

          else {

            _result = null;

          }

        }

        finally {

          _reply.recycle();

          _data.recycle();

        }

        return _result;

      }

      public static com.gss.aidl.IPostManager sDefaultImpl;

    }

    static final int TRANSACTION_getBookList = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);

    static final int TRANSACTION_addBook = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);

    static final int TRANSACTION_getBook = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);

    public static boolean setDefaultImpl(com.gss.aidl.IPostManager impl) {

      // Only one user of this interface can use this function

      // at a time. This is a heuristic to detect if two different

      // users in the same process use this function.

      if (Stub.Proxy.sDefaultImpl != null) {

        throw new IllegalStateException("setDefaultImpl() called twice");

      }

      if (impl != null) {

        Stub.Proxy.sDefaultImpl = impl;

        return true;

      }

      return false;

    }

    public static com.gss.aidl.IPostManager getDefaultImpl() {

      return Stub.Proxy.sDefaultImpl;

    }

  }

  public java.util.List<com.gss.aidl.Post> getBookList() throws android.os.RemoteException;

  public void addBook(com.gss.aidl.Post book) throws android.os.RemoteException;

  public com.gss.aidl.Post getBook() throws android.os.RemoteException;

}

DESCRIPTOR

Binder的唯一标识,一般用当前Binder类名标识。

asInterface(android.os.IBinder obj)

用于将服务端的Binder对象转换成客户端所需的AIDL接口类型对象,如果同进程调用Stub本身,不同调用系统封装的Stub.proxy对象

asBinder

此方法用于返回当前的Binder对象

onTransact

这个方法运行在Binder线程池中,当客户端法强跨进程请求是,远程请求会通过系统封装后交给此方法处理。

其他就是Proxy的方法了,里面基本就是实现AIDL接口代码。

注意:AIDL是同步的,如果远程方法很耗时,不能UI线程中请求。其次,服务端的Binder方法运行在Binder的线程池中,所有Binder方法无论是否耗时都采用同步的方式实现,因为它已经运行在一个线程中了。

从上面看,我们完全可以不用AIDL文件可以实现Binder,之所以使用AIDL,是为了方便,系统自动帮生成代码,我们自己可以手动写一个Binder,主要是是一个Binder的接口,继承了IInterface接口,然后是内部Stub类,这个类就是Binder,内部实现了IBookManager接口中的方法,在Service中调用这个Stub对象。手动实现步骤:

1.声明AIDL接口,只需要继承IInterface接口,里面只有一个asBinder方法。

2.实现Stub类和Stub类中的Proxy代理类。

3.远程调用

接下来介绍Binder的linkToDeath和unlinkToDeath方法,处理Binder连接断裂的问题,设置一个死亡代理。

首先需要声明一个DeathRecipient接口,实现这个接口,当Binder死亡的时候会回调里面的BinderDied方法。

private IBinder.DeathRecipient mDeathRecipient=new IBinder.DeathRecipient() {

    @Override

    public void binderDied() {

        if(mBookManager==null){

            return;

        }

        mBookManager.asBinder().unlinkToDeath(mDeathRecipient,0);

        mBookManager=null;

        //这里重新绑定远程服务

    }

};

客户端设置代理

mServiec= IMessageBoxManager.Stub.asInterface(binder);

binder.linkToDeath(mDeathRecipient,0);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时代我西

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值