【问题标题】:Should I use AIDL or not?我应该使用 AIDL 吗?
【发布时间】:2017-04-21 01:24:48
【问题描述】:

使用AIDL 有什么好处,而我们可以使用java 接口 来帮助客户端应用程序调用绑定的服务?

例如,对于ITestService,我们应该创建一个AIDL,如下所示:

// ITestService.aidl
package com.varanegar.vaslibrary.service;

// Declare any non-default types here with import statements

interface ITestService {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
        double aDouble, String aString);
    int test();
}

那么我们应该实现生成的Stub类:

public class TestService extends Service {
    public class TestImpl extends ITestService.Stub{

        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, 
           float aFloat, double aDouble, String aString) throws RemoteException {

        }

        @Override
        public int test() throws RemoteException {
            return 0;
        }
    }
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return new TestImpl();
    }
}

不过,我相信我们可以像这样轻松地创建一个 java 接口:

interface ITestService {
    int test();
}

然后创建实现该接口的服务:

public class TestService extends Service implements ITestService {
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int test() {
        return 0;
    }
}

根据维基百科:

AIDL:基于 Java,适用于 Android;支持本地和远程过程 调用,可以通过调用从本机应用程序访问 Java 原生接口 (JNI)

还有其他令人信服的理由使用AIDL 代替普通的 java 服务吗?

在我看来,我可以在没有任何AIDL 的情况下使用绑定和启动服务。因为这可以在 android 库中编写 java 接口作为服务器和所有客户端应用程序之间的合同。

我不打算创建本机应用程序。因此,如果AIDL 用于将 Java 服务公开给本机应用程序,那么在我的情况下使用它是否正确?我对吗?如果我误解了AIDL,请纠正我。

提前致谢

【问题讨论】:

  • 如果我理解正确,你是对的,但这里的区别是你不是公开一个库而是一个后台服务,因此你需要 AIDL,以便 Android 内部可以将定义公开给所有应用程序需要它。您是否尝试过在没有 AIDL 的情况下公开服务,并且成功了?
  • “然后创建实现该接口的服务”——你可以这样做,但它没有用。在您的场景中,服务的客户端无权访问 Service 对象。 “根据维基百科”——维基百科是不正确的,因为 AIDL 与 JNI 关系不大。 “而不是普通的java服务?” -- 什么是“普通的 java 服务”? “在我看来,我可以在没有任何 AIDL 的情况下使用绑定和启动服务。” -- 在一个进程内,是的,但不是跨进程。
  • 顺便说一句,process1 服务与 process2 活动通信的另一种方式是通过洞穴人文件。

标签: android idl aidl


【解决方案1】:

来自documentation

仅当您允许来自不同应用程序的客户端访问您的 IPC 服务并希望在您的服务中处理多线程时,才需要使用 AIDL。如果您不需要跨不同应用程序执行并发 IPC,您应该通过implementing a Binder 创建您的接口,或者,如果您想执行 IPC,但不需要处理多线程,请实现您的接口@ 987654323@。无论如何,在实施 AIDL 之前,请确保您了解 Bound Services

【讨论】:

    【解决方案2】:

    AIDL 什么都不做,只是让系统生成隐藏绑定 IPC 详细信息的样板代码,以便您可以调用远程服务 API 作为本地方法调用。所以,

    1. 如果您不需要 IPC(即,您的客户端和服务器保持在同一个 过程),你不需要AIDL;

    2. 如果您想自己编写 IPC 的样板代码,则不需要 AIDL;

    3. 如果您的服务不够复杂(即不需要并发多线程访问),您可以使用系统提供的 IPC Messenger API。您不需要自己的 AIDL,因为 Messenger API 隐藏了 AIDL 的使用;

    4. 为了扩展案例 3,如果您可以使用任何现有的库或现有的 API 来访问另一个进程中的服务,则不需要自己的 AIDL。例如,您可以使用现有的系统 API 访问 ActivityManagerService,而 IActivityManager 的所有 AIDL 内容都被系统 API 隐藏。

    【讨论】:

    • 据我所知。进程 1 中的函数无法访问进程 2 中的内存。祝你好运@Xiao Feng​​span>
    • @JaveneCPPMcGowan 这里的“访问”并不是指访问另一个进程的内存,而是特指“使用另一个进程提供的服务”。我相信在谈论 AIDL 的上下文中含义很清楚,尤其是在给出示例的情况下。
    【解决方案3】:

    顺便说一句,process1 服务与 process2 活动通信的另一种方式是通过洞穴人文件。服务写入一个文件。 Activity 读取文件并响应另一个文件上的服务。在文件上调用文件读取循环,该循环应该阻塞,直到将字节写入其中。在单独的线程上执行此操作。

    【讨论】:

      猜你喜欢
      • 2020-04-17
      • 2011-12-26
      • 2021-12-10
      • 2010-12-25
      • 2014-05-27
      • 2010-12-25
      • 2018-09-11
      • 2012-07-02
      • 2010-10-29
      相关资源
      最近更新 更多