java - Activity 指示器和线程黑莓

标签 java multithreading blackberry

我正在开发一个项目,我从网上下载一个文件,它并不大,只有一些KB。

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

我在单独的线程中下载文件,以免阻塞主线程。但我对 Activity 指示器有疑问。我使用 UiApplication.getUiApplication().invokeLater(//CODE); 从管理器中删除标签并添加 Activity 指示器并启动它。它是否正确?我是在文件下载线程中完成的,是不是需要从主线程调用GUI代码?

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

但是,这并不能按预期工作,因为最后一个 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();
                }
            });
        }
    }

最佳答案

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

  1. 继续使用invokeLater,并存储一些 boolean 字段(或一些等效字段),告诉您下载是否完成以及 Activity 指示器是否显示。在您的第一个 invokeLater 中,您只会在下载尚未完成时显示指示器;在第二个 invokeLater 中,您只需删除已显示的指示器。
  2. 使用invokeAndWait而不是 invokeLaterinvokeAndWait 将尽快调用 runnable,并停止当前线程的执行,直到调用 runnable。这将减少将发生的并行化量,但无论如何更改字段都是一个快速操作,因此在这种情况下应该不会太重要
  3. 不要将 invokeAndWaitRunnable 一起使用,而是在添加和删除的代码周围使用 synchronized(Application.getEventLock()) block 字段。只要在应用程序的事件锁上进行同步,您甚至可以在 UI 线程之外操作 UI。 This article详细讨论一下事件锁。

我会推荐第三个选项,因为它是最强大的。但是,您应该注意,某些操作(例如弹出模式对话框)只能从 UI 线程完成(仅持有事件锁是不够的)。在这些情况下,您需要选择其他两个选项之一。但是,从您描述您尝试执行的操作的方式来看,在这种情况下持有事件锁应该足够了。

关于java - Activity 指示器和线程黑莓,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6513557/

相关文章:

java - 如何使用 aws Lambda 和 JAVA 将项目放入 aws DynamoDb 中

java - android studio 自动完成 : how to display constructors with parameters

c# - 我必须向我的 Web API REST 方法添加显式线程吗?

java - 如何检测 BlackBerry 设备的屏幕方向是 "natural"?

java - 如何将参数从 php 发送到 blackberry/Java 移动应用程序

java - 如何解决Java中的r=g编译问题?

java - IntelliJ IDEA,关闭在格式化/保存实例变量之前插入 'final' 关键字(JAVA)

c# - 在另一个线程上捕获异常?

python - 如何直接在python代码中的tesseract中配置OMP_THREAD_LIMIT以禁用多处理?

BlackBerry Horizo​​ntalFieldManager 对齐