我正在为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
,我保证就是这种情况。至少,我无法想到从oneway
到IServer.doSomething()
的来电可以立即返回(IClient.reportBack()
应该确保什么),但oneway
仍然是能够在同一个线程中递归重新调用IClient.reportBack
。必须启动IServer中的新线程,否则旧的IServer线程可以重新用于对IServer.doSomething()的内部调用,但仅在外部调用IServer.doSomething
后才返回。
所以我的问题是,一切都按我认为的方式运作吗? Android文档几乎没有提及IServer.doSomething()
接口。
答案 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)仍然同步执行。
如果我们在客户端应用中使用多个线程调用服务端服务,服务端的方法会异步执行