Android:如何实现“分布式控制”

时间:2011-05-26 17:06:56

标签: android design-patterns

{与android-developers论坛的交叉道歉。那里没有收到任何答案}

我有一个有趣的设计挑战:

我有一个前端(Activity)和一个后端(用本机C / C ++编写) 码。后端是一个复杂的对象,部分控制 应用流程&一旦开始运行它自己的线程。所以我有 “分布式控制”场景。

活动需要能够异步发送消息到 后端然后采取某些行动。但后端也需要 能够异步发送消息到Activity,到哪个 它通过chnaging UI,触发方法等来响应。

基本上我需要的是一个双向倾听者。

所以后端向屏幕发送消息(拍照,提示用户,获取 位置,现在拍另一张照片等)和屏幕做它需要的东西 去做。但另外,屏幕也应该可以调用了 后端 - 监听器发回消息(捕获的摄像机图像,系统 在...的回调中生成 - “我被暂停/销毁”消息等) 这些事件。主要问题是这都是异步的。

这可能没有紧耦合吗?这甚至可能吗?

我已经想到了Asynctask / handlers(但那是一条单行道 通知UI线程),观察者模式(两个对象都将是 观察者/观察者?)但对于从哪里开始感到困惑。有什么想法吗, 链接会非常有帮助。

2 个答案:

答案 0 :(得分:2)

在您的本机代码中,您可以使用JNI从VM获取类(和对象),一旦获得了类(或对象),就可以找到方法并调用它们(类的静态方法,所有对象的方法)。在我看来,简单的解决方案是在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 *,并且调用isInterrupted()方法的简单分配/调用/释放代码行是:

if (JavaThread(env).isInterrupted()) { ... }

答案 1 :(得分:0)

如何使用阻塞队列,因为您的描述让我想起并行编程类中的经典生产者 - 消费者问题。

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

HTH