" pushModalScreen由非事件线程&QUOT调用;扔在事件线程 [英] "pushModalScreen called by a non-event thread" thrown on event thread

查看:114
本文介绍了" pushModalScreen由非事件线程&QUOT调用;扔在事件线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让我的黑莓应用程序显示一个定制的模态对话框,并具有开放的线程等待,直到用户关闭该对话框屏幕。

I am trying to get my Blackberry application to display a custom modal dialog, and have the opening thread wait until the user closes the dialog screen.

final Screen dialog = new FullScreen();

...// Fields are added to dialog

Application.getApplication().invokeAndWait(new Runnable()
{

    public void run()
    {
        Application.getUiApplication().pushModalScreen(dialog);             
    }
});

这是抛出一个异常,它说pushModalScreen由非事件线程被称为尽管我使用invokeAndWait从事件线程中调用pushModalScreen。

This is throwing an Exception which says "pushModalScreen called by a non-event thread" despite the fact that I am using invokeAndWait to call pushModalScreen from the event thread.

关于真正的问题是什么任何想法?

Any ideas about what the real problem is?

下面是code复制此问题:

Here is the code to duplicate this problem:

package com.test;

import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;

public class Application extends UiApplication {
    public static void main(String[] args)
    {
        new Application();
    }

    private Application()
    {
        new Thread()
        {
            public void run()
            {
                Application.this.enterEventDispatcher();
            }
        }.start();

        final Screen dialog = new FullScreen();
        final ButtonField closeButton = new ButtonField("Close Dialog");
        closeButton.setChangeListener(new FieldChangeListener()
        {

            public void fieldChanged(Field field, int context)
            {
                Application.getUiApplication().popScreen(dialog);
            }
        });
        dialog.add(closeButton); 
        Application.getApplication().invokeAndWait(new Runnable()
        {

            public void run()
            {
                try
                {
                    Application.getUiApplication().pushModalScreen(dialog);
                }
                catch (Exception e)
                {
                    // To see the Exception in the debugger
                    throw new RuntimeException(e.getMessage());
                }
            }
        });

        System.exit(0);
    }
}

我使用的组件包版本4.5.0。

I am using Component Package version 4.5.0.

推荐答案

这是最大Gontar的观测建立,使用的invokeLater来代替invokeAndWait时没有抛出异常,全面的解决方案是实现invokeAndWait正确出来的invokeLater和Java的同步方法

Building on Max Gontar's observation that the Exception is not thrown when using invokeLater instead of invokeAndWait, the full solution is to implement invokeAndWait correctly out of invokeLater and Java's synchronization methods:

public static void invokeAndWait(final Application application,
    final Runnable runnable)
{
    final Object syncEvent = new Object();
    synchronized(syncEvent)
    {
        application.invokeLater(new Runnable()
        {

            public void run()
            {   
                runnable.run();
                synchronized(syncEvent)
                {
                    syncEvent.notify();
                }
            }
        });
        try
        {
            syncEvent.wait();
        }
        catch (InterruptedException e)
        {
            // This should not happen
            throw new RuntimeException(e.getMessage());
        }
    }
}

不幸的是,invokeAndWait方法不能被覆盖,所以必须谨慎使用,而不是把这种静态版本。

Unfortunately, the invokeAndWait method cannot be overridden, so care must be used to call this static version instead.

这篇关于" pushModalScreen由非事件线程&QUOT调用;扔在事件线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆