AIDL的简单使用

       AIDL是Android Interface Definition Language的缩写,即为Android接口定义语言。安卓系统中会有多个进程,每个进程都是相互独立的,无法共享内存。想要共享进程间的数据,就需要进程通信,AIDL即为IPC机制(跨进程通信)的一种。

FW向app层提供的接口大多使用的就是AIDL(还有使用广播的,例如Home按键、蓝牙连接,USB接续等等),封装在了framework.jar中了。

接下来进入主题,看看DIAL怎么使用。

首先在main的路径下新建一个文件夹为aidl。

在aidl文件夹中新建一个aidl文件IEx.aidl

在IEx.aidl文件中写出客户端需要使用的接口

package com.android.ex;
interface IEx {
    /**
     * control ex
     */
    oneway void controlEx();

}

以上写完之后对项目进行build,build完成之后会生成对应的IEx.java文件

/*
 * This file is auto-generated.  DO NOT MODIFY.
 */
package com.android.ex;
public interface IEx extends android.os.IInterface
{
  /** Default implementation for IEx. */
  public static class Default implements com.android.ex.IEx
  {
    /**
         * control ex
         */
    @Override public void controlEx() throws android.os.RemoteException
    {
    }
    @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.android.ex.IEx
  {
    private static final java.lang.String DESCRIPTOR = "com.android.ex.IEx";
    /** Construct the stub at attach it to the interface. */
    public Stub()
    {
      this.attachInterface(this, DESCRIPTOR);
    }
    /**
     * Cast an IBinder object into an com.android.ex.IEx interface,
     * generating a proxy if needed.
     */
    public static com.android.ex.IEx asInterface(android.os.IBinder obj)
    {
      if ((obj==null)) {
        return null;
      }
      android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
      if (((iin!=null)&&(iin instanceof com.android.ex.IEx))) {
        return ((com.android.ex.IEx)iin);
      }
      return new com.android.ex.IEx.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_controlEx:
        {
          data.enforceInterface(descriptor);
          this.controlEx();
          return true;
        }
        default:
        {
          return super.onTransact(code, data, reply, flags);
        }
      }
    }
    private static class Proxy implements com.android.ex.IEx
    {
      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;
      }
      /**
           * control ex
           */
      @Override public void controlEx() throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          boolean _status = mRemote.transact(Stub.TRANSACTION_controlEx, _data, null, android.os.IBinder.FLAG_ONEWAY);
          if (!_status && getDefaultImpl() != null) {
            getDefaultImpl().controlEx();
            return;
          }
        }
        finally {
          _data.recycle();
        }
      }
      public static com.android.ex.IEx sDefaultImpl;
    }
    static final int TRANSACTION_controlEx = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
    public static boolean setDefaultImpl(com.android.ex.IEx 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.android.ex.IEx getDefaultImpl() {
      return Stub.Proxy.sDefaultImpl;
    }
  }
  /**
       * control ex
       */
  public void controlEx() throws android.os.RemoteException;
}

接下来是我们的服务端代码,AIDL的实现使用的binder机制,所以服务端需要再Service的onBind方法中返回Stub的实例。

import android.app.Service
import android.content.Intent
import android.os.IBinder
import com.android.ex.IEx

class ExService : Service() {

    override fun onBind(intent: Intent): IBinder {
        return ExImpl()
    }

    override fun onCreate() {
        super.onCreate()

    }

    inner class ExImpl : IEx.Stub() {
        override fun controlEx() {
            TODO("Not yet implemented")
        }
    }
}

客户端实现代码如下:


import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.IBinder
import android.util.Log
import com.android.ex.IEx

/**
 * @ClassName Ex
 * @Author LZD
 * @Date 2024/1/24 11:20
 * @Description
 */
class Ex : IEx {
    companion object {
        private var sInstance: Ex? = null
    }

    private var mService: IEx? = null


    fun getInstance(): Ex? {
        if (null == sInstance) {
            synchronized(Ex::class) {
                if (null == sInstance) {
                    sInstance = Ex()
                }
            }
        }
        return sInstance
    }

    private val connection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            mService = IEx.Stub.asInterface(service)
            try {
                mService?.asBinder()?.linkToDeath({
                    mService = null
                    getService()
                }, 0);
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }

        override fun onServiceDisconnected(name: ComponentName?) {
            mService = null
        }

    }
    private lateinit var mContext: Context
    public fun bind(context: Context) {
        mContext = context
        getService()
    }

    public fun unBind() {
        if (null != mContext) {
            mContext.unbindService(connection);
        }
    }

    @Synchronized
    private fun getService(): IEx? {
        if (null == mService) {
            var intent = Intent();
            val cn = ComponentName("com.android.ex", "com.android.ex.ExService")
            intent.setComponent(cn)
            mContext.bindService(intent, connection, Context.BIND_AUTO_CREATE)
        }
        return mService
    }

    override fun asBinder(): IBinder = mService!!.asBinder()

    override fun controlEx() {
        if (mService != null) {
            try {
                mService?.controlEx()
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
}

以上为AIDL的简单使用方法。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AIDLAndroid Interface Definition Language)是一种用于 Android 平台的接口定义语言,它可以帮助不同进程之间的组件进行通信。下面是使用 AIDL 进行进程间通信的步骤: 1.定义 AIDL 接口 首先,在服务端和客户端之间定义一个 AIDL 接口。在 AIDL 文件中,定义需要向客户端公开的方法和参数。 2.实现 AIDL 接口 在服务端中,实现定义的 AIDL 接口,并在 onCreate() 方法中将其注册到系统中。 3.绑定服务端 在客户端中,使用 bindService() 方法绑定服务端。 4.获取 AIDL 接口实例 在客户端中,实现 ServiceConnection 接口,当服务端连接成功时,会回调 onServiceConnected() 方法。在此方法中,可以获取到 AIDL 接口实例。 5.调用 AIDL 接口方法 在客户端中,通过获取到的 AIDL 接口实例,即可调用服务端暴露的方法。 下面是一个简单的示例代码: 服务端: ``` //定义 AIDL 接口 interface IMyAidlInterface { int add(int a, int b); } //实现 AIDL 接口 class MyAidlInterfaceImpl extends IMyAidlInterface.Stub { @Override public int add(int a, int b) throws RemoteException { return a + b; } } //在 onCreate() 方法中注册 AIDL 接口 @Override public void onCreate() { super.onCreate(); Intent intent = new Intent(this, MyAidlInterfaceService.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); Log.i(TAG, "MyAidlInterfaceService is created."); } //定义 ServiceConnection 对象,以便在客户端连接时获取 AIDL 接口实例 private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mIMyAidlInterface = IMyAidlInterface.Stub.asInterface(service); Log.i(TAG, "MyAidlInterfaceService is connected."); } @Override public void onServiceDisconnected(ComponentName name) { mIMyAidlInterface = null; Log.i(TAG, "MyAidlInterfaceService is disconnected."); } }; ``` 客户端: ``` //定义 ServiceConnection 对象 private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { //获取 AIDL 接口实例 mIMyAidlInterface = IMyAidlInterface.Stub.asInterface(service); Log.i(TAG, "MyAidlInterfaceService is connected."); } @Override public void onServiceDisconnected(ComponentName name) { mIMyAidlInterface = null; Log.i(TAG, "MyAidlInterfaceService is disconnected."); } }; //使用 bindService() 方法绑定服务端 Intent intent = new Intent(); intent.setComponent(new ComponentName("com.example.myaidlservice", "com.example.myaidlservice.MyAidlInterfaceService")); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); //调用服务端暴露的方法 int result = mIMyAidlInterface.add(1, 2); ``` 希望这个简单的示例可以帮助你了解如何使用 AIDL 进行进程间通信。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值