Android .aidl中的单向声明是否保证在单独的线程中调用该方法?

时间:2010-06-14 23:45:26

标签: java android multithreading aidl

我正在为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()需要再发出一次{{1}调用}。

这里的问题是IClient.doSomething()通常不会是可重入的。只要在新线程中始终调用IServer.doSomething(),这没关系。在这种情况下,我可以确保IClient.reportBack()的实现始终是IServer.doSomething(),以便从新线程调用阻塞直到第一次调用返回。

如果一切按照我认为的方式工作,那么通过将IClient接口声明为synchronized,我保证就是这种情况。至少,我无法想到从onewayIServer.doSomething()的来电可以立即返回(IClient.reportBack()应该确保什么),但oneway仍然是能够在同一个线程中递归重新调用IClient.reportBack。必须启动IServer中的新线程,否则旧的IServer线程可以重新用于对IServer.doSomething()的内部调用,但仅在外部调用IServer.doSomething后才返回。

所以我的问题是,一切都按我认为的方式运作吗? Android文档几乎没有提及IServer.doSomething()接口。

2 个答案:

答案 0 :(得分:17)

oneway关键字意味着如果该调用导致IPC(即调用者和被调用者处于不同进程中),则调用进程将不等待被调用进程处理IPC。如果它不会导致IPC(即它们都在同一个进程中),则呼叫将是同步的。这是一个令人遗憾的细节,它简化了绑定器IPC的实现。如果它们在同一个进程中,则调用只是一个常规的java方法调用。

答案 1 :(得分:0)

来自安卓文档

<块引用>

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

例如,我们有一个 Client app 和一个 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 app like

调用服务器服务
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

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

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

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

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