【问题标题】:IBinder between Bound Service and Activity绑定服务和活动之间的IBinder
【发布时间】:2017-09-12 06:36:03
【问题描述】:

也许我只是累了。但是我很难理解 IBinder 接口是如何工作的。

服务有一个方法调用 onBind(Intent intent),这会将某种形式的 IBinder 传递给绑定活动。

我苦苦挣扎的是如何将其可视化。 IBinder 对象是否是服务和活动之间的管道,以便活动可以直接与服务交互?还是 IBinder 是一个传递给 Activity 的对象,其中包含来自 Service 的信息(类似于 Intent)?

编辑:这个想法是让我能够从绑定活动中调用 getSomeData 函数。或者更确切地说,这个想法是让 mSomeData 对象加入活动。

我正在使用以下类,我试图找出从服务中获取活动请求数据(如果需要,可序列化,但我不想)的最佳方式。

public class MainService extends Service{

    private CustomBinder mIBinder;
    private SomeDataObject mSomeData;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        mIBinder = new CustomBinder();
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public CustomBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
    // This is auto generated and I havent changed it yet. I am not
    // Experiencing errors as this is not designed to run yet.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    public final SomeDataObject getSomeData(){
        return mSomeData;
    }

    class SomeBinder extends MainEngineBinder{
        // All the Auto Generated Stuff
    }
}

【问题讨论】:

  • 第一种情况——客户端activity可以在返回的binder上调用transact()方法,而onTransact()会在服务端被调用
  • 这很有趣。我会玩一点。那么在活页夹中添加返回对象的方法的正确方法是什么?
  • 什么对象?和什么方法?你的意思是AIDL 方法吗?还是只是没有任何高级 AIDL 的原始 IBinder?
  • 我想我不知道该如何回答。我将编辑我的帖子以显示我正在修补的内容的一些背景。我目前没有使用 AIDL。
  • @pskink 我在帖子中添加了一些代码

标签: android android-intent


【解决方案1】:

您无需了解IBinder 的工作原理。只需子类Binder(不是IBinder)并向Binder 子类添加一些方法。这些方法可以从绑定到您的服务的活动中调用。

在您的情况下,最简单的方法是让内部类扩展Binder,然后该内部类将能够从您的服务访问方法/字段并将它们返回给活动。您看起来像是在使用与 Android documentation on bound services 类似的模板,所以这是文档中的示例 - 在这种情况下,绑定器所做的所有事情都是公开一个获取服务本身的 getter,调用者可以简单地调用方法 直接在服务上:

public class LocalService extends Service {
    // Binder given to clients
    private final IBinder mBinder = new LocalBinder();
    // Random number generator
    private final Random mGenerator = new Random();

    /**
     * Class used for the client Binder.  Because we know this service always
     * runs in the same process as its clients, we don't need to deal with IPC.
     */
    public class LocalBinder extends Binder {
        LocalService getService() {
            // Return this instance of LocalService so clients can call public methods
            return LocalService.this;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    /** method for clients */
    public int getRandomNumber() {
      return mGenerator.nextInt(100);
    }
}

调用 bind() 的调用者需要将 IBinder 转换为 LocalService.LocalBinder。在这种情况下,IBinder 既不是管道也不是类似意图的对象;它是一个普通的 Java 风格的界面。

请注意,如果您进行 IPC,所有这些都适用。 The documentation 声明在这种情况下(相同的应用程序,相同的进程)调用是一个普通的 Java 调用 - 你可以传递对象、引用,任何你喜欢的,因为一切都在同一个进程中。

请注意,IPC、管道、编组、序列化等都是不必要的(除非您希望从其他应用程序调用您的服务,或者如果您使用多进程应用程序)。 Android 服务甚至不会在单独的线程中运行,除非您明确启动一个新线程,并且没有它的“自己的”线程或进程——对绑定器或服务对象本身的所有调用都与调用者在同一个线程中进行.

就您而言,Android 文档中的确切示例似乎是最好的方法。

【讨论】:

    猜你喜欢
    • 2018-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多