代码之家  ›  专栏  ›  技术社区  ›  Dan Menes

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

  •  6
  • Dan Menes  · 技术社区  · 15 年前

    我正在为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() 总是在新线程中调用。在这种情况下,我可以确保 总是 synchronized 适当地使来自新线程的调用阻塞,直到第一个调用返回。

    oneway ,我保证是这样。至少,我想不出有什么办法 IServer.doSomething() IClient.reportBack() 可以马上回来(什么 是应该确保的) IClient.reportBack 还能再回忆吗 IServer.doSomething 在同一线程中递归。必须启动IServer中的新线程,否则旧的IServer线程可以重新用于对IServer.doSomething()的内部调用,但只能在对的外部调用之后使用 他回来了。

    单向

    1 回复  |  直到 15 年前
        1
  •  21
  •   joeo    15 年前

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

        2
  •  0
  •   Linh    4 年前

    来自Android文档

    oneway关键字修改远程调用的行为。使用时,远程呼叫不会阻塞;它只发送事务数据并立即返回。接口的实现最终以常规调用的形式接收来自绑定线程池的常规调用,作为常规远程调用。如果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 影响 中的方法 客户端应用程序 (远程呼叫)。
    客户端应用程序 喜欢

    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 从单个线程(主线程)开始,以便函数可以阻塞。所以我想 单向

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