Гарантирует ли одностороннее объявление в Android .aidl, что метод будет вызываться в отдельном потоке? - PullRequest
7 голосов
/ 15 июня 2010

Я разрабатываю платформу для клиент-серверного приложения для телефонов 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() на IClient.reportBack() может вернуться немедленно (что должно гарантировать oneway), но IClient.reportBack все еще сможет рекурсивно вызывать IServer.doSomething вта же нить.Либо новый поток в IServer должен быть запущен, либо старый поток IServer может быть повторно использован для внутреннего вызова IServer.doSomething (), но только после того, как внешний вызов IServer.doSomething() вернется.

Итак, мой вопрос: все ли работает так, как я думаю?В документации Android едва упоминаются интерфейсы oneway.

1 Ответ

17 голосов
/ 15 июня 2010

Ключевое слово oneway означает, что если этот вызов приводит к IPC (то есть вызывающий и вызываемый абоненты находятся в разных процессах), то вызывающий процесс не будет ждать, пока вызываемый процесс обработает IPC.Если это не приводит к IPC (т.е. они оба в одном и том же процессе), вызов будет синхронным.Это печальная деталь, которая значительно упрощает реализацию Binder IPC.Если они находятся в одном и том же процессе, вызов является обычным вызовом метода Java.

...