8

我正在为 Android 手机的客户端/服务器应用程序设计一个框架。我对 Java 和 Android 都很陌生(但对一般编程或特别是线程编程并不陌生)。

有时我的服务器和客户端会在同一个进程中,有时它们会在不同的进程中,具体取决于具体的用例。客户端和服务器接口如下所示:

IServer.aidl:

package com.my.application;

interface IServer {

    /**
     * Register client callback object
     */
    void registerCallback( in IClient callbackObject );

    /**
     * Do something and report back
     */
    void doSomething( in String what );
  .
  .
  .
}

IClient.aidl:

package com.my.application;

oneway interface IClient {

    /**
     * Receive an answer
     */
    void reportBack( in String answer );
  .
  .
  .
}

现在这里是有趣的地方。我可以预见客户端调用的用例,IServer.doSomething()然后调用IClient.reportBack(),并根据报告回来的内容,IClient.reportBack()需要再次调用IClient.doSomething().

这里的问题是,IServer.doSomething()一般来说,它不会是可重入的。没关系,只要IClient.reportBack()总是在新线程中调用。在这种情况下,我可以确保 的实现IServer.doSomething()总是synchronized适当的,以便来自新线程的调用阻塞,直到第一个调用返回。

如果一切都按照我认为的方式运行,那么通过将 IClient 接口声明为oneway,我保证会如此。至少,我想不出任何方式来调用IServer.doSomething()toIClient.reportBack()可以立即返回(oneway应该确保什么),但IClient.reportBack仍然能够IServer.doSomething在同一个线程中递归地重新调用。要么必须启动 IServer 中的新线程,要么旧的 IServer 线程可以重新用于对 IServer.doSomething() 的内部调用,但只有在外部调用IServer.doSomething()返回之后。

所以我的问题是,一切都按照我的想法进行吗?Android 文档几乎没有提到oneway接口。

4

2 回答 2

23

oneway 关键字意味着如果该调用导致IPC(即调用者和被调用者在不同的进程中),那么调用进程将不会等待被调用进程处理IPC。如果它没有导致 IPC(即它们都在同一个进程中),则调用将是同步的。这是一个不幸的细节,大大简化了 binder IPC 的实现。如果它们在同一个进程中,则调用只是一个常规的 java 方法调用。

于 2010-06-15T04:28:06.660 回答
1

来自安卓文档

oneway 关键字修改远程调用的行为。使用时,远程调用不会阻塞;它只是发送交易数据并立即返回。接口的实现最终从Binder线程池接收这个作为常规调用作为常规远程调用。如果 oneway 与本地调用一起使用,则没有影响,调用仍然是同步的

例如,我们有 aClient app和 a Server app,并且an AIDL interface喜欢

interface IRemoteService {
     oneway void onewayFunctionCall(int value); // function take 1 seconds to complete
     void noneOneWayFunctionCall(int value); // function take 1 seconds to complete
}

oneway影响Client app(远程调用)中的方法。
例如,我们从Client applike调用服务器服务

for (i in 0..5) {
    Log.i("TAG", "call $i") // fired each 1 second
    iRemoteService?.noneOneWayFunctionCall(i)
}
// run synchronous
for(i in 0..5) {
    serverService.onewayFunctionCall(i); // fired right after previous function call
}
// run asynchronous

因为 oneway 方法调用并且不等待结果所以它必须是 void function.

在上述情况下,我们server service从单个线程(主线程)调用,因此函数可以阻塞。所以我认为oneway只在单个线程中有用。

如果我们从客户端应用程序中的单个线程调用,服务器中的方法(oneway / none oneway)仍然同步执行。

如果我们在客户端应用中使用多线程调用服务端服务,服务端中的方法会异步执行

于 2021-02-01T10:01:32.100 回答