刷新屏幕更新ListField用新的数据 [英] Refresh Screen to Update ListField with new Data

查看:301
本文介绍了刷新屏幕更新ListField用新的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是ListField控件来显示XML Web服务返回的数据。我想刷新ListField或屏幕每分钟有新的记录或数据来更新ListField。

我试着用下面的code,但它不能正常工作(这是挂)。

 公共MyApp的(){
    //按屏幕上的UI栈进行渲染。
    UiApplication.getUiApplication()的invokeLater(Runnable的新(){
        公共无效的run(){
            。UiApplication.getUiApplication()pushScreen(新自选());
        }
    },5000,真正的);
}
ResponseHandler所处理=新ResponseHandler所();
ListField listUsers =新ListField(handler.getItem()大小());公共自选画面(){
    的setTitle(yQAforum);
    //获取来自Web服务的XML
    串wsReturnString = GlobalV.Fetch_Webservice(myDs);
    //解析返回的XML
    SAXParserImpl的SAXParser =新SAXParserImpl();
    ByteArrayInputStream的流=新ByteArrayInputStream进行(wsReturnString.getBytes());
    尝试{
        saxparser.parse(流处理器);
    }
    赶上(例外五){
        response.setText(无法​​解析响应。);
    }
    //从处理程序类返回矢量诗
    listUsers.setSize(handler.getItem()大小());
    listUsers.setCallback(本);
    listUsers.setEmptyString(未找到用户,0);
    加(listUsers);
}


解决方案

您正试图从UI线程上的Web服务获取数据。这几乎总是错误的做法。

在UI线程(也称为的主要的线程),负责通过触控板/轨迹球绘制UI,并跟踪用户的行为,如触摸,或导航。如果UI线程被阻塞,等待远程Web服务器的响应,它不能服务的用户界面。

有一对夫妇的变化,你应该:

公共MyApp的(){
    //按屏幕上的UI栈进行渲染。
    UiApplication.getUiApplication()的invokeLater(Runnable的新(){
        公共无效的run(){
            。UiApplication.getUiApplication()pushScreen(新自选());
        }
    },5000,真正的);
}

应改为

公共MyApp的(){
    //按屏幕上的UI栈进行渲染。
    pushScreen(新自选());
}

MyApp的()构造就已经被称为UI线程上,所以没有必要使用的invokeLater()来执行UI线程上的 pushScreen()电话。它已经将被称为UI线程上,如果从 MyApp的构造器中运行。此外,5000毫秒的延迟是不是真的有帮助。这只是5秒,哪些用户会讨厌耽误您的应用程序的启动。

如果你想实现一个启动画面,或者类似的东西,当应用程序启动时,请搜索黑莓闪屏堆栈溢出,我敢肯定,你会发现结果。

现在,一旦创建了自选类,你应该照顾的不可以来从UI线程Web服务的结果。在自选构造函数将在UI线程上运行。如果你愿意,你可以的启动的后台线程Web服务请求,一旦画面显示。做到这一点的方法之一是使用 onUiEngineAttached()

保护无效onUiEngineAttached(附布尔){
    如果(附后){
        // TODO:你可能想显示某种动画
        //进度界面这里,所以用户知道您正在获取数据        定时器定时器=新的Timer();
        //安排Web服务任务运行每分钟
        timer.schedule(新WebServiceTask(),0,60 * 1000);
    }
}公共自选画面(){
    的setTitle(yQAforum);    listUsers.setEmptyString(未找到用户,0);
    listUsers.setCallback(本);
    加(listUsers);
}私有类WebServiceTask扩展的TimerTask {
    公共无效的run(){
        //获取来自Web服务的XML
        串wsReturnString = GlobalV.Fetch_Webservice(myDs);
        //解析返回的XML
        SAXParserImpl的SAXParser =新SAXParserImpl();
        ByteArrayInputStream的流=新ByteArrayInputStream进行(wsReturnString.getBytes());
        尝试{
           saxparser.parse(流处理器);
        }
        赶上(例外五){
           response.setText(无法​​解析响应。);
        }
        //现在,更新UI后面的UI线程上:
        UiApplication.getUiApplication()的invokeLater(Runnable的新(){
           公共无效的run(){
              // TODO:记录当前选择,或专注,行              //从处理程序类返回矢量诗
              listUsers.setSize(handler.getItem()大小());
              //注意:如果你没有看到列表内容更新,您可能需要调用
              // listUsers.invalidate();
              //此处强制刷新。我不记得,如果调用的setSize()是不够的。              // TODO:设置previously选择,或专注,行
           }
        });
    }
}

您将需要添加一些错误处理的情况下,网络服务不响应,或超过一分钟时间较长(你不会想被做一个新的请求时,如果最后一个没有完成)。

不过,这应该让你开始。

注意:一旦你修复与UI线程上运行的网络code中的问题,您可能的还是的发现,你的code不起作用。有可能是在获取网络服务数据的问题。你必须调试。我只是向你展示有一个的问题与code公布。如果您仍然有与Web服务问题获取,张贴另一个问题(固定在UI线程问题)。谢谢你。

I am using a ListField Control to display data returned from xml webservice. I want to refresh the ListField or the screen every minute to update the ListField with new records or data.

I tried using the code below but it is not working properly (It is hanging).

public MyApp() {
    // Push a screen onto the UI stack for rendering.
    UiApplication.getUiApplication().invokeLater(new Runnable() {
        public void run() {
            UiApplication.getUiApplication().pushScreen(new MyScreen());
        }
    },5000,true);
}
ResponseHandler handler = new ResponseHandler();
ListField listUsers = new ListField(handler.getItem().size());

public MyScreen() {
    setTitle("yQAforum");
    //Fetch the xml from the web service
    String wsReturnString = GlobalV.Fetch_Webservice("myDs");
    //Parse returned xml
    SAXParserImpl saxparser = new SAXParserImpl();
    ByteArrayInputStream stream = new ByteArrayInputStream(wsReturnString.getBytes());
    try {
        saxparser.parse( stream, handler );
    } 
    catch ( Exception e ) {
        response.setText( "Unable to parse response.");
    }
    //Return vector sze from the handler class
    listUsers.setSize(handler.getItem().size());
    listUsers.setCallback(this);
    listUsers.setEmptyString("No Users found", 0);
    add(listUsers);
}

解决方案

You are attempting to fetch data from your webservice on the UI thread. That's almost always the wrong thing to do.

The UI thread (also known as the main thread) is responsible for drawing the UI, and tracking user actions, like touches, or navigation via a trackpad/trackball. If the UI thread is blocked waiting for a remote web server to respond, it cannot service the UI.

There's a couple changes you should make:

public MyApp() {
    // Push a screen onto the UI stack for rendering.
    UiApplication.getUiApplication().invokeLater(new Runnable() {
        public void run() {
            UiApplication.getUiApplication().pushScreen(new MyScreen());
        }
    },5000,true);
}

should be changed to

public MyApp() {
    // Push a screen onto the UI stack for rendering.
    pushScreen(new MyScreen());
}

The MyApp() constructor will already be called on the UI thread, so there is no need to use invokeLater() to perform the pushScreen() call on the UI thread. It already will be called on the UI thread, if run from within the MyApp constructor. Also, the 5000 msec delay isn't really helpful. This will just delay the startup of your app by 5 seconds, which users will hate.

If you are trying to implement a splash screen, or something similar, when the app starts up, please search stack overflow for "BlackBerry splash screen", and I'm sure you'll find results.

Now, once your MyScreen class is created, you should take care not to fetch web service results from the UI thread. The MyScreen constructor will be run on the UI thread. If you want, you can initiate a web service request on a background thread, once the screen is shown. One way to do that is to use onUiEngineAttached():

protected void onUiEngineAttached(boolean attached) {
    if (attached) {
        // TODO: you might want to show some sort of animated
        //  progress UI here, so the user knows you are fetching data

        Timer timer = new Timer();
        // schedule the web service task to run every minute
        timer.schedule(new WebServiceTask(), 0, 60*1000);
    }
}

public MyScreen() {
    setTitle("yQAforum");

    listUsers.setEmptyString("No Users found", 0);
    listUsers.setCallback(this);
    add(listUsers);
}

private class WebServiceTask extends TimerTask {
    public void run() {
        //Fetch the xml from the web service
        String wsReturnString = GlobalV.Fetch_Webservice("myDs");
        //Parse returned xml
        SAXParserImpl saxparser = new SAXParserImpl();
        ByteArrayInputStream stream = new ByteArrayInputStream(wsReturnString.getBytes());
        try {
           saxparser.parse( stream, handler );
        } 
        catch ( Exception e ) {
           response.setText( "Unable to parse response.");
        }
        // now, update the UI back on the UI thread:
        UiApplication.getUiApplication().invokeLater(new Runnable() {
           public void run() {
              // TODO: record the currently selected, or focused, row

              //Return vector sze from the handler class
              listUsers.setSize(handler.getItem().size());
              // Note: if you don't see the list content update, you might need to call
              //   listUsers.invalidate();
              // here to force a refresh.  I can't remember if calling setSize() is enough.

              // TODO: set the previously selected, or focused, row
           }
        });
    }
}

You'll need to add some error handling, in case the web service doesn't respond, or takes longer than a minute (you wouldn't want to be making a new request, if the last one hadn't finished).

But, this should get you started.

Note: once you fix the problem with running network code on the UI thread, you may still find that your code doesn't work. There could be problems fetching the web service data. You'll have to debug that. I am only showing you one problem with the code posted. If you still have problems with the web service fetch, post another question (with the UI thread problem fixed). Thanks.

这篇关于刷新屏幕更新ListField用新的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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