首页 > 解决方案 > 具有多个值的 AIDL 中的回调

问题描述

我想在aidl(aosp)android中实现一个回调函数,它应该传输多个值而不是一个。如何解决?使用对对象?或者有没有其他更好的方法?

标签: androidandroid-sourceaidl

解决方案


这是一个用 Java 实现返回自定义对象的 AIDL 回调的示例。

接口规范

  • SomeResult.aidl

    您将为要通过活页夹传输的自定义类定义 AIDL。

    package com.example;
    
    parcelable SomeResult;
    
  • ISomeCallback.aidl

    您的回调会有一个 AIDL。请注意,这会导入 parcelable 的先前 AIDL。

    package com.example;
    
    import com.example.SomeResult;
    
    interface ISomeCallback {
      SomeResult getResult();
    }
    
  • ISomeService.aidl

    您将有一个 AIDL 用于您的服务。您的服务可能有一些将回调作为输入的方法。当然,也可以有一个返回回调的方法,这取决于你想要做什么。

    package com.example;
    
    import com.example.ISomeCallback;
    
    interface ISomeService {
      void someAction(ISomeCallback callback);
    }
    

执行

然后,您可以编写实现这些接口的 Java 类。

  • SomeResult.java

    parcelable 类型必须实现Parcelable接口。您必须提供有关如何将自定义类写入/读取到/从Parcel. 通常这是通过将类的每个成员写入包裹然后以相同的顺序再次读取它们来完成的。

    package com.example;
    
    import android.os.Parcel;
    import android.os.Parcelable;
    
    public class SomeResult implements Parcelable {
      private String someData1;
      private String someData2;
    
      public SomeResult(String someData1, String someData2) {
        this.someData1 = someData1;
        this.someData2 = someData2;
      }
    
      @Override
      public int describeContents() {
        return 0; // No special data, such as file descriptors
      }
    
      @Override
      public void writeToParcel(Parcel out, int flags) {
        out.writeString(someData1);
        out.writeString(someData2);
      }
    
      public static final Parcelable.Creator<SomeResult> CREATOR = new Parcelable.Creator() {
        public SomeResult createFromParcel(Parcel in) {
          return new SomeResult(in.readString(), in.readString());
        }
    
        public SomeResult[] newArray(int size) { return new SomeResult[size]; }
      };
    }
    
  • SomeCallback.java

    然后,在您的回调中,您将构建自定义类的新实例并返回它。

    package com.example;
    
    import com.example.ISomeCallback;
    import com.example.SomeResult;
    
    public class SomeCallback extends ISomeCallback.Stub {
      @Override
      public SomeResult getResult() {
        return new SomeResult("Hello", "world!");
      }
    }
    
  • SomeService.java 您将实现接受回调的服务的方法。在该方法中,您可以调用回调来获取自定义类的实例。

    package com.example;
    
    import android.os.RemoteException;
    import com.example.ISomeService;
    
    public class SomeService extends ISomeService.Stub {
      @Override
      public void someAction(ISomeCallback callback) throws RemoteException {
        SomeResult result = callback.getResult();
    
        // ...
      }
    }
    

用法

例如,要使用您的服务,您可以从服务管理器获取代理对象(假设您的服务作为系统服务运行,如果您的服务通过其他方式运行,则获取代理对象的方式会有所不同)。然后,您将构建回调类的实例并使用回调作为参数调用服务方法:

    ISomeService someService = ISomeService.Stub.asInterface(
        ServiceManager.getService("some_service"));

    ISomeCallback someCallback = new SomeCallback();

    try {
        someService.someAction(someCallback);
    } catch (RemoteException ex) {
        // TODO Handle error
    }

推荐阅读