您正在尝试从 UI 线程上的 Web 服务获取数据。这几乎总是错误的做法。
UI 线程(也称为主线程)负责绘制 UI,并跟踪用户操作,如触摸,或通过触控板/轨迹球进行导航。如果 UI 线程在等待远程 Web 服务器响应时被阻塞,则它无法为 UI 提供服务。
您应该进行一些更改:
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);
}
应该改为
public MyApp() {
// Push a screen onto the UI stack for rendering.
pushScreen(new MyScreen());
}
构造MyApp()
函数将已经在 UI 线程上调用,因此无需使用在 UI 线程上invokeLater()
执行pushScreen()
调用。MyApp
如果从构造函数中运行,它将在 UI 线程上调用。此外,5000 毫秒的延迟并没有真正的帮助。这只会将您的应用程序的启动延迟 5 秒,这是用户会讨厌的。
如果您正在尝试实现启动画面或类似的东西,当应用程序启动时,请在堆栈溢出中搜索“黑莓启动画面”,我相信您会找到结果。
现在,一旦您的MyScreen
类被创建,您应该注意不要从 UI 线程获取 Web 服务结果。构造MyScreen
函数将在 UI 线程上运行。如果需要,您可以在屏幕显示后在后台线程上发起Web 服务请求。一种方法是使用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
}
});
}
}
您需要添加一些错误处理,以防 Web 服务没有响应或花费超过一分钟的时间(如果最后一个请求尚未完成,您不希望发出新请求)。
但是,这应该让你开始。
注意:一旦你解决了在 UI 线程上运行网络代码的问题,你可能仍然会发现你的代码不起作用。获取 Web 服务数据可能存在问题。你必须调试它。我只向您展示发布代码的一个问题。如果您仍然对 Web 服务获取有问题,请发布另一个问题(已修复 UI 线程问题)。谢谢。