活动指示灯和线程黑莓 [英] Activity indicator and threads blackberry

查看:149
本文介绍了活动指示灯和线程黑莓的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的工作,我从网上下载文件的一个项目,它只是一些知识库系统并不大。

我的布局与它下面的标签列表。当用户更新(检查是否新文件是可用的)我想用活动的指标来代替标签。

我下载的文件在一个单独的线程不会阻塞主线程。但我与活动的指标问题。我使用 UiApplication.getUiApplication()的invokeLater(// code); 删除从经理的标签,并添加活动的指标,以及启动它。它是否正确?我这样做是在文件下载线程,不是它的权利,你需要从主线程调用GUI code?

然后我有code块(这一切是文件下载线程的run方法中),这将下载报告,然后我有一个新的的invokeLater 方法,该方法消除了活动的指标,并再次添加的标签。

然而,由于预期从上次的invokeLater code是第一个之前运行这不起作用。我曾与对话测试。我怎么能解决这个问题?

我希望它运行在顺序code在I codeD它,而另一端之前没有code运行。我怎么能做到呢?

(是的,我知道这是乱了!)

 私有类UpdateReportThread继承Thread {
        公共无效的run(){
            super.run();            UiApplication.getUiApplication()的invokeLater(Runnable的新(){
                公共无效的run(){
                    鉴于=新ActivityIndi​​catorView(Field.FIELD_HCENTER);
                    模型=新ActivityIndi​​catorModel();
                    控制器=新ActivityIndi​​catorController();                    view.setController(控制器);
                    view.setModel(模型);
                    controller.setModel(模型);
                    controller.setView(视图);
                    model.setController(控制器);                    位图位图= Bitmap.getBitma $ P $的PSource(spinner.jpg);
                    view.createActivityImageField(位图,图5,Field.FIELD_HCENTER);                    dialogManager =新VerticalFieldManager(Manager.FIELD_HCENTER | Manager.FIELD_VCENTER | Manager.USE_ALL_HEIGHT);
                    dialogManager.add(新的LabelField(请稍候...,Field.FIELD_HCENTER));
                    dialogManager.add(视图);                    加(dialogManager);
                    view.getModel()恢复()。                    删除(lblIssueWeek);
                    删除(lblIssueYear);
                }
            });
            //文件下载code
                    //文件下载code
                    //文件下载code            UiApplication.getUiApplication()的invokeLater(Runnable的新(){
                公共无效的run(){
                    view.getModel()取消()。
                    删除(dialogManager);                    lblIssueWeek =新的LabelField(,LabelField.FIELD_HCENTER);
                    lblIssueYear =新的LabelField(,LabelField.FIELD_HCENTER);
                    加(lblIssueWeek);
                    加(lblIssueYear);
                    updateCurrentIssue();
                }
            });
        }
    }


解决方案

如果你看到的invokeLater 可运行正在不正确的顺序运行,那么就好像你有三个选项​​:


  1. 继续使用的invokeLater和存储一些布尔字段(或某些等效),告诉你下载是否完成,活动指示灯是否显示。在你的第一个的invokeLater ,你只会显示该指标如果下载尚未完成;在你的第二个的invokeLater ,如果已经显示出它,你只会取下指示器。

  2. 使用<一个href=\"http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/system/Application.html#invokeAndWait%28java.lang.Runnable%29\"相对=> invokeAndWait 的nofollow的,而不是的invokeLater invokeAndWait 将调用可运行尽快,并会在当前线程停止执行,直到可运行被调用。这将减少并行化时将发生的金额,但变化领域是一个快速的操作呢,这样不应该太大的关系在这种情况下

  3. 而不是使用 invokeAndWait 的Runnable ,使用同步(Application.getEventLock ())围绕code,增加和删除领域块。你可以操纵UI外连UI线程的,只要你在应用程序的事件锁同步。 本文谈多一点有关事件的锁。

我建议第三个选项,因为它是最强大的。然而,你应该知道,有一定的操作,如雨后春笋般冒出来一个模式对话框,可以从UI线程完成(持有本事件的锁是不够的)。在这种情况下,你需要去与其他两个选项之一。然而,从你的方式描述了你正在尝试做的,抱着事件锁应该是在这种情况下就足够了。

I am working on a project where I download from a file from the web, it is not big only some KBs.

My layout is a list with a label below it. When the user updates (checks if new file is available) I want to replace the label with the activity indicator.

I download the file in a separate thread to not block the main thread. But I have problems with the activity indicator. I use UiApplication.getUiApplication().invokeLater(//CODE); to remove the label from the manager and add the activity indicator, as well as starting it. Is this correct? I do it in the file downloading thread, and isnt it right that you need to invoke GUI code from the main thread?

then I have block of code (all of this is inside the run method of the file downloading thread) which downloads the report then I have a new invokeLater method which removes the activity indicator and adds the label again.

However this does not work as expected since the last invokeLater code is run before the first one. I have tested with dialogs. How could I solve this?

I want it to run the code in the order in I coded it in, and no code run before the other ends. How could I accomplish that?

(and yes, I know this is messy!)

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();
                }
            });
        }
    }

解决方案

If you are seeing invokeLater runnables being run in the incorrect order, then it seems like you have three options:

  1. Continue to use invokeLater, and store some boolean fields (or some equivalent) that tell you whether the download is complete, and whether the activity indicator is showing. In your first invokeLater, you would only show the indicator if the download has not completed; and in your second invokeLater, you would only remove the indicator if it has been shown.
  2. Use invokeAndWait instead of invokeLater. invokeAndWait will call the runnable as soon as possible, and will halt execution in the current thread until the runnable has been called. This will reduce the amount of parallelization that will occur, but changing fields is a quick operation anyway so that shouldn't matter too much in this case
  3. Instead of using invokeAndWait with a Runnable, use a synchronized(Application.getEventLock()) block around the code that adds and removes fields. You can manipulate the UI even outside of the UI thread, so long as you are synchronized on the application's event lock. This article talks a little bit more about event locks.

I would recommend the third option, since it is the most robust. However, you should be aware that there are certain operations, such as popping up a modal dialog box, that can only be done from the UI thread (holding the event lock is not sufficient). In those cases, you would need to go with one of the other two options. However, from the way you described what you are trying to do, holding the event lock should be sufficient in this situation.

这篇关于活动指示灯和线程黑莓的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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