7

我试图了解管理 UI 交互的三种方法之间的区别。

在尝试在真实案例中弄清楚这三个术语时,我真的很困惑。

下面的代码显示了 invokeAndWait 方法的功能,但如果我用 invokeLater 或 getEventLock() 替换它,程序将以完全相同的方式工作。

有人可以修改代码以显示更新 UI 的三种方法之间的差异吗?

public final class HelloWorldMainScreen extends MainScreen
{
    private LabelField labelField;
    public HelloWorldMainScreen()
    {        
        labelField = new LabelField("Hello World");       
        add(labelField);
        MainScreenUpdaterThread thread = new MainScreenUpdaterThread(this);
        thread.start();
    }

    public void appendLabelText(String text){
        labelField.setText(labelField.getText()+"\n"+text);
    }
}

public class MainScreenUpdaterThread extends Thread {
    HelloWorldMainScreen mainScreen;

    public MainScreenUpdaterThread(HelloWorldMainScreen mainScreen){
        this.mainScreen = mainScreen;
    }

    public void run(){
        for (int i = 0; i < 10; i++) {
            try{
                Thread.sleep(5000);
            }catch(InterruptedException ex){};
            UiApplication.getUiApplication().invokeAndWait(new Runnable() {

                public void run() {
                    mainScreen.appendLabelText("Update");                   
                }
            });
        }
    }
}

这三个概念对于许多初学者来说非常混乱,因此任何描述其功能的解释性源代码对任何人都将非常有帮助,我认为。

提前致谢!

4

2 回答 2

6

我对三种不同方法的理解:

  • Application.getEventLock()- 尽快获得事件锁
  • UiApplication.invokeLater()- 放入Runnable事件队列,它将在之前放入此队列的所有其他任务之后执行
  • UiApplication.invokeAndWait()- 与前一个相同,除了调用线程将停止,直到Runnable将运行

我个人的意见是从不使用第一种方法。我不认为我的任何绘制或 UI 更改任务比其他已放入事件队列的任务更优先。

我主要使用第二种方法,当我实现一些模态弹出对话框选择时,我使用了最后一种方法。

于 2012-12-24T20:30:04.653 回答
2

getEventLock():获取应用程序用户界面事件锁。如果工作线程希望执行使用事件线程序列化的代码,则应在此线程上同步。您的工作线程应该只在短时间内持有锁,因为此操作会暂停线程调度程序。

任何涉及设备用户界面的操作都必须在保持锁定的情况下完成。UI 系统还保证它调用的任何方法都将在已经拥有锁的线程上执行。

应用程序永远不应调用 notify 或等待此对象。

invokeLater():将可运行对象放入此应用程序的事件队列。调用此方法,传递一个可运行对象,以便在处理完所有未决事件后,在调度线程上调用该对象的 run() 方法。

如果没有事件分派线程(即 hasEventThread() 返回 false),则当队列超过其大小限制时,将丢弃要排队的最后一项。注意:如果应用程序没有事件线程,您可以调用 setAcceptEvents(boolean) 来通知运行时系统该应用程序不再接受事件。然后丢弃该应用程序排队的所有事件。

invokeAndWait():将可运行对象放入此应用程序的事件队列中,并等待它被处理。调用此方法,传递一个可运行对象,以便在处理完所有未决事件后,在调度线程上调用该对象的 run() 方法。

此方法阻塞,直到插入事件被处理(即,直到可运行对象的 run() 方法返回)。

在事件分派线程上调用此方法是安全的。在这种情况下,runnable 将立即执行。

如果没有事件分派线程(即 hasEventThread() 返回 false),则当队列超过其大小限制时,将丢弃要排队的最后一项。注意:如果应用程序没有事件线程,您可以调用 setAcceptEvents(boolean) 来通知运行时系统该应用程序不再接受事件。然后丢弃该应用程序排队的所有事件。

API 文档:http ://www.blackberry.com/developers/docs/4.3.0api/net/rim/device/api/system/Application.html#invokeLater(java.lang.Runnable )

于 2012-12-26T17:49:40.553 回答