Android 接口定义语言 (AIDL)

Posted xhBruce

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 接口定义语言 (AIDL)相关的知识,希望对你有一定的参考价值。

android 接口定义语言 (AIDL)

查看 android developer上 AIDL 概览Android 接口定义语言 (AIDL)


1. 使用AIDL

  • IRemoteService.aidl编译自动生成对应IRemoteService.java文件,需要IRemoteService.Stub mBinder = new IRemoteService.Stub() ...
  • 目录结构,同一app中在AndroidManifest.xml中,把service配置成android:process=":remote"演示
  • 运行查看

1.1 什么情况使用AIDL

只有在需要不同应用的客户端通过 IPC 方式访问服务,并且希望在服务中进行多线程处理时,您才有必要使用 AIDL。如果您无需跨不同应用执行并发 IPC,则应通过实现 Binder 来创建接口;或者,如果您想执行 IPC,但不需要处理多线程,请使用 Messenger 来实现接口。无论如何,在实现 AIDL 之前,请您务必理解绑定服务。

1.2 AIDL实质是什么

查看 AIDL对应生成的IRemoteService.java文件,客户端获取asInterface(android.os.IBinder obj),服务端实现class Stub extends android.os.Binder。原理实质是利用framework binder的架构
AIDL 使用 Binder 内核驱动程序进行调用。当您发出调用时,系统会将方法标识符和所有对象打包到某个缓冲区中,然后将其复制到某个远程进程,该进程中有一个 Binder 线程正在等待读取数据。Binder 线程收到某个事务的数据后,该线程会在本地进程中查找原生桩对象,然后此类会解压缩数据并调用本地接口对象。此本地接口对象正是服务器进程所创建和注册的对象。当在同一进程和同一后端中进行调用时,不存在代理对象,因此直接调用即可,无需执行任何打包或解压缩操作。

/*
 * This file is auto-generated.  DO NOT MODIFY.
 */
package com.xhbruce.aidldemo;
// Declare any non-default types here with import statements

public interface IRemoteService extends android.os.IInterface

  /** Default implementation for IRemoteService. */
  public static class Default implements com.xhbruce.aidldemo.IRemoteService
  
    /**
         * Demonstrates some basic types that you can use as parameters
         * and return values in AIDL.
         */
    @Override public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException
    
    
    @Override public int getPid() throws android.os.RemoteException
    
      return 0;
    
    @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.xhbruce.aidldemo.IRemoteService
  
    private static final java.lang.String DESCRIPTOR = "com.xhbruce.aidldemo.IRemoteService";
    /** Construct the stub at attach it to the interface. */
    public Stub()
    
      this.attachInterface(this, DESCRIPTOR);
    
    /**
     * Cast an IBinder object into an com.xhbruce.aidldemo.IRemoteService interface,
     * generating a proxy if needed.
     */
    public static com.xhbruce.aidldemo.IRemoteService asInterface(android.os.IBinder obj)
    
      if ((obj==null)) 
        return null;
      
      android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
      if (((iin!=null)&&(iin instanceof com.xhbruce.aidldemo.IRemoteService))) 
        return ((com.xhbruce.aidldemo.IRemoteService)iin);
      
      return new com.xhbruce.aidldemo.IRemoteService.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_basicTypes:
        
          data.enforceInterface(descriptor);
          int _arg0;
          _arg0 = data.readInt();
          long _arg1;
          _arg1 = data.readLong();
          boolean _arg2;
          _arg2 = (0!=data.readInt());
          float _arg3;
          _arg3 = data.readFloat();
          double _arg4;
          _arg4 = data.readDouble();
          java.lang.String _arg5;
          _arg5 = data.readString();
          this.basicTypes(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);
          reply.writeNoException();
          return true;
        
        case TRANSACTION_getPid:
        
          data.enforceInterface(descriptor);
          int _result = this.getPid();
          reply.writeNoException();
          reply.writeInt(_result);
          return true;
        
        default:
        
          return super.onTransact(code, data, reply, flags);
        
      
    
    private static class Proxy implements com.xhbruce.aidldemo.IRemoteService
    
      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;
      
      /**
           * Demonstrates some basic types that you can use as parameters
           * and return values in AIDL.
           */
      @Override public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException
      
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        try 
          _data.writeInterfaceToken(DESCRIPTOR);
          _data.writeInt(anInt);
          _data.writeLong(aLong);
          _data.writeInt(((aBoolean)?(1):(0)));
          _data.writeFloat(aFloat);
          _data.writeDouble(aDouble);
          _data.writeString(aString);
          boolean _status = mRemote.transact(Stub.TRANSACTION_basicTypes, _data, _reply, 0);
          if (!_status && getDefaultImpl() != null) 
            getDefaultImpl().basicTypes(anInt, aLong, aBoolean, aFloat, aDouble, aString);
            return;
          
          _reply.readException();
        
        finally 
          _reply.recycle();
          _data.recycle();
        
      
      @Override public int getPid() throws android.os.RemoteException
      
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        int _result;
        try 
          _data.writeInterfaceToken(DESCRIPTOR);
          boolean _status = mRemote.transact(Stub.TRANSACTION_getPid, _data, _reply, 0);
          if (!_status && getDefaultImpl() != null) 
            return getDefaultImpl().getPid();
          
          _reply.readException();
          _result = _reply.readInt();
        
        finally 
          _reply.recycle();
          _data.recycle();
        
        return _result;
      
      public static com.xhbruce.aidldemo.IRemoteService sDefaultImpl;
    
    static final int TRANSACTION_basicTypes = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
    static final int TRANSACTION_getPid = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
    public static boolean setDefaultImpl(com.xhbruce.aidldemo.IRemoteService 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.xhbruce.aidldemo.IRemoteService getDefaultImpl() 
      return Stub.Proxy.sDefaultImpl;
    
  
  /**
       * Demonstrates some basic types that you can use as parameters
       * and return values in AIDL.
       */
  public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, java.lang.String aString) throws android.os.RemoteException;
  public int getPid() throws android.os.RemoteException;

以上是关于Android 接口定义语言 (AIDL)的主要内容,如果未能解决你的问题,请参考以下文章

Android AIDL(安卓接口定义语言)基本使用方法

Android AIDL(安卓接口定义语言)基本使用方法

AIDL(Android Interface Definition LanguageAndroid接口定义语言)

入门篇:10.Android中AIDL(安卓接口定义语言)跨应用操作Service

AIDL安卓接口定义语言

Android中AIDL的使用