活动指示器和线程黑莓

时间:2011-06-28 21:55:07

标签: java multithreading blackberry

我正在开发一个项目,我从网上下载文件,它不仅仅是一些KB。

我的布局是一个下面有标签的列表。当用户更新(检查新文件是否可用)时,我想用活动指示符替换标签。

我在单独的线程中下载文件以不阻止主线程。但是我的活动指标存在问题。我使用UiApplication.getUiApplication().invokeLater(//CODE);从管理器中删除标签并添加活动指示器,然后启动它。它是否正确?我是在文件下载线程中做的,你不需要从主线程中调用GUI代码吗?

然后我有代码块(所有这些都在文件下载线程的run方法内)下载报告然后我有一个新的invokeLater方法,它删除活动指示符并再次添加标签。

但是,由于最后一个invokeLater代码在第一个之前运行,因此无法正常工作。我已经测试了对话框。我怎么能解决这个问题?

我希望它按照我编码的顺序运行代码,并且在其他代码结束之前没有代码运行。我怎么能做到这一点?

(是的,我知道这很麻烦!)

private class UpdateReportThread extends Thread {
        public void run() {
            super.run();

            UiApplication.getUiApplication().invokeLater(new Runnable() {
                public void run() {
                    view = new ActivityIndicatorView(Field.FIELD_HCENTER);
                    model = new ActivityIndicatorModel();
                    controller = new ActivityIndicatorController();

                    view.setController(controller);
                    view.setModel(model);
                    controller.setModel(model);
                    controller.setView(view);
                    model.setController(controller);    

                    Bitmap bitmap = Bitmap.getBitmapResource("spinner.jpg");
                    view.createActivityImageField(bitmap, 5, Field.FIELD_HCENTER);

                    dialogManager = new VerticalFieldManager(Manager.FIELD_HCENTER | Manager.FIELD_VCENTER | Manager.USE_ALL_HEIGHT);
                    dialogManager.add(new LabelField("Please wait...", Field.FIELD_HCENTER));
                    dialogManager.add(view);

                    add(dialogManager);     
                    view.getModel().resume();

                    delete(lblIssueWeek);
                    delete(lblIssueYear);
                }
            });


            //File downloading code
                    //File downloading code
                    //File downloading code    

            UiApplication.getUiApplication().invokeLater(new Runnable() {
                public void run() {
                    view.getModel().cancel();
                    delete(dialogManager);

                    lblIssueWeek = new LabelField("", LabelField.FIELD_HCENTER);
                    lblIssueYear = new LabelField("", LabelField.FIELD_HCENTER);
                    add(lblIssueWeek);
                    add(lblIssueYear);
                    updateCurrentIssue();
                }
            });
        }
    }

2 个答案:

答案 0 :(得分:2)

如果您看到invokeLater runnables以错误的顺序运行,那么您似乎有三个选择:

  1. 继续使用invokeLater,并存储一些布尔字段(或某些等效字段),告诉您下载是否完整,以及活动指示器是否显示。在您的第一个invokeLater中,您只会在下载尚未完成时显示指标;在您的第二个invokeLater中,您只会删除指示符(如果已显示)。
  2. 使用invokeAndWait代替invokeLaterinvokeAndWait将尽快调用runnable,并将暂停当前线程中的执行,直到调用runnable为止。这将减少将发生的并行化的数量,但是无论如何改变字段都是一个快速操作,因此在这种情况下不应该太重要
  3. 不要将invokeAndWaitRunnable一起使用,而是在添加和删除字段的代码周围使用synchronized(Application.getEventLock())块。只要在应用程序的事件锁定上进行同步,您甚至可以在UI线程之外操作UI。 This article更多地谈论事件锁定。
  4. 我会推荐第三种选择,因为它是最强大的。但是,您应该知道某些操作(例如弹出模式对话框)可以从UI线程完成(保持事件锁定是不够的)。在这些情况下,您需要使用其他两个选项之一。但是,从你描述你想要做的事情的方式来看,在这种情况下持有事件锁就足够了。

答案 1 :(得分:0)

找到这个帖子

Blackberry - Loading/Wait screen with animation

这是显示请等待指示符的好例子。