Android: как реализовать «распределенное управление» - PullRequest
4 голосов
/ 26 мая 2011

{Извиняюсь за кросс-пост с форума разработчиков android. Там не получили никаких ответов}

У меня есть интересная задача дизайна:

У меня есть веб-интерфейс (Activity) и бэкэнд (написанный на родном C / C ++) код. Бэкэнд представляет собой сложный объект, который частично контролирует Поток приложения и однажды запущенный работает в своем собственном потоке. Так что я сценарий «распределенного управления».

Активность должна иметь возможность асинхронно отправлять сообщения бэкэнд, который затем выполняет определенные действия. Но бэкэнд также нуждается чтобы иметь возможность асинхронно отправлять сообщения в активность, к которой он отвечает, изменяя пользовательский интерфейс, методы стрельбы и т. д.

По сути, мне нужен двусторонний слушатель.

Итак, бэкэнд отправляет сообщение на экран (сфотографируй, подскажи пользователю, получи местоположение, сделайте еще один снимок сейчас и т. д.) сделать. Но кроме того, экран также должен быть в состоянии вызвать backend-слушатель для отправки обратно сообщений (снятое изображение с камеры, система сгенерировано - сообщение "Я получил паузу / уничтожено" и т. д.) в обратных вызовах эти события. Основная проблема в том, что это все асинхронно.

Возможно ли это без жесткой связи? Это вообще возможно?

Я думал об Asynctask / обработчиках (но это улица с односторонним движением для информирование потока пользовательского интерфейса), шаблон наблюдателя (оба объекта будут наблюдатель / наблюдаемый?) но не понимает, с чего начать. Какие-нибудь мысли, ссылки были бы очень полезны.

Ответы [ 2 ]

2 голосов
/ 26 мая 2011

В вашем собственном коде вы можете использовать JNI для получения классов (и объектов) из вашей виртуальной машины, и как только вы получите класс (или объект), вы можете найти методы и вызвать их (статические методы для класса, всеметоды для объекта).Мне кажется, что простое решение заключается в предоставлении помощника в вашем Java-классе, который инкапсулирует нативные методы и содержит вызов нативного кода.

В прошлом мне нужно было определить нативный кодесли его поток был прерван на уровне Java.Java предоставляет java.lang.Thread.currentThread () в качестве статического элемента для поиска собственного потока, а java.lang.Thread.isInterrupted () для [неразрушающего] определения статуса прерывания.Я использовал следующее, чтобы решить эту проблему на родном уровне;возможно, вы можете использовать его для своих нужд (конечно, с соответствующей адаптацией к отправке сообщений):

/* JavaThread: this class is a simple wrapper to be used around    */
/* JNI's Thread class. It locates the provided functions as needed */
/* and when it is destroyed (such as going out of scope) it will   */
/* release its local references.                                   */
class JavaThread
{
public:
    JavaThread(JNIEnv *env)
    {
        mEnv = env;

        /* find the Java Thread class within the JVM: */
        mThread = mEnv->FindClass("java/lang/Thread");

        /* find the Thread.currentThread() method within the JVM: */
        mCurrentThreadMID = mEnv->GetStaticMethodID(mThread, "currentThread", "()Ljava/lang/Thread;");

        /* find the current thread's isInterrupted() method: */
        mIsInterruptedMID = mEnv->GetMethodID(mThread, "isInterrupted", "()Z");
    }
    ~JavaThread()
    {
        if (mThread)
        {
            mEnv->DeleteLocalRef(mThread);
            mThread = 0;
        }
    }

    bool isInterrupted() {
        bool bResult;
        if (!mThread)           return false;
        if (!mIsInterruptedMID) return false;

        /* find the current thread (from the JVM's perspective): */
        jobject jCurrentThread = (jobject)mEnv->CallStaticObjectMethod(mThread, mCurrentThreadMID);
        if (NULL == jCurrentThread) return false;

        /* see if the current thread is interrupted */
        bResult = (bool)mEnv->CallBooleanMethod(jCurrentThread, mIsInterruptedMID);

        /* delete the current thread reference */
        mEnv->DeleteLocalRef(jCurrentThread);

        /* and return the result */
        return bResult;
    }

private:
    JNIEnv    *mEnv;
    jclass     mThread;
    jmethodID  mCurrentThreadMID;
    jmethodID  mIsInterruptedMID;
};

Инстанцирование основано на JNIEnv *, предоставленном вашему нативному методу, и простом allocate / call / deallocateСтрока кода для вызова метода isInterrupted ():

if (JavaThread(env).isInterrupted()) { ... }
0 голосов
/ 26 мая 2011

Как насчет использования очереди блокировки, потому что ваше описание напоминает мне классическую проблему производителя-потребителя из класса параллельного программирования.

http://en.wikipedia.org/wiki/Producer-consumer_problem

Также Java 1.5, похоже, имеет реализацию очереди блокировки, я не могу вспомнить, если она доступна на Android.

http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html

Я предполагаю, что вы можете установить 2 однонаправленные очереди блокировки для связи в каждом направлении. Q1 будет иметь передний конец как производитель, а задний как потребитель. Q2 будет иметь интерфейс в качестве потребителя и сервер в качестве производителя.

Также вы можете использовать шаблон проектирования «Команда» для сообщений «сообщения».

http://en.wikipedia.org/wiki/Command_pattern

НТН

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...