Android / Java: как вызвать методы объекта, созданного в другом потоке? - PullRequest
3 голосов
/ 28 января 2011

В моем приложении Android NDK библиотека C ++ работает в потоке, отличном от потока пользовательского интерфейса. Вызов JNI из C ++ создает экземпляр класса Java Foo. Я хотел бы иметь еще один объектный бар Java, созданный в потоке пользовательского интерфейса, для вызова методов в Foo. Как я могу это сделать?

Бонус сложности: у Foo есть несколько собственных методов, которые вызывают соответствующие функции JNI из библиотеки C ++. Как я могу гарантировать, что эти вызовы потокобезопасны?

Бонус за сложность 2: некоторые методы Bar на самом деле переопределяют методы обратного вызова, в частности WebViewClient. Код возврата некоторых методов зависит от результата вызова метода Фу. Так что вызов Фу должен был произойти немедленно.

Ответы [ 4 ]

0 голосов
/ 01 апреля 2011

Возможно, я бы попытался использовать что-то вроде beginInvoke() для правильной постановки сообщения в поток. здесь было отмечено, что beginInvoke() может быть смоделировано либо с Activity.runOnUiThread(), либо с правильно использованным AsyncTask().

0 голосов
/ 27 февраля 2011

Итак, у вас есть потоки 1 и 2, поток 2 создает объект, а поток 1 имеет объект, который хочет вызвать методы объекта в потоке 2.

Не могли бы вы, по сути, не иметь объект в потоке 2, написанный на Java, со стандартными методами синхронизации потоков Java, такими как использование синхронизированного ключевого слова?

например, код Java в теме:

    // object of this type instantiated on thread 2 and called from thread 1
public class thread2Class  {
    public void doSomething(...) {
        synchronized (this) {
           // call java or jni mthod
        }
    }
 }
0 голосов
/ 04 марта 2011

Двойная очередь сообщений с подпрограммой обратного вызова уведомителя, встроенной в сообщение.Тема 1 публикует сообщение с обратным адресом в очереди 2.Поток 2 обрабатывает сообщение и публикует уведомление о результате в очереди потока 1. Поток 1 вызывает процедуру обратного вызова, связанную с отправленным исходным сообщением.Очередь потока 1 - это очередь сообщений пользовательского интерфейса, а поток 2 - ваша собственная предпочтительная реализация очереди.Поток 2 - менеджер / оболочка для библиотечных вызовов.Нет блокировки, нет ожидания.Если поток 1 должен управлять состоянием, он должен обновить модель состояния, которая контролирует, какое сообщение публикуется после получения ответа.

0 голосов
/ 28 января 2011

Попробуйте класс Handler.Создайте обработчик в конструкторе Foo.Передайте ссылку на класс Bar как-нибудь.Пусть Bar вызывает Handler.post ().

Чтобы это работало, поток должен иметь очередь сообщений.Если это чисто рабочий поток, то вызов методов напрямую не является ответом;нет механизма прерывания потока AFAIR.Для передачи содержимого в рабочий поток вам необходимо несколько смоделировать очередь сообщений - иметь очередь объектов Runnnable (которые добавит Bar) и время от времени проверять ее.

Обеспечение безопасности потока - это отдельная большаявопрос.ТАК недостаточно для всего, что было сказано и сделано по этой теме.

...