黑莓多线程问题

Posted

技术标签:

【中文标题】黑莓多线程问题【英文标题】:Blackberry multi threading issue 【发布时间】:2012-01-11 18:16:14 【问题描述】:

我正在开发一个通过 HTTP 请求 (javax.microedition.io.HttpConnection) 与服务器通信的 BlackBerry 应用程序。在设备上,用户单击一些 UI 项,设备将请求发送到服务器,当响应到来时,UI 会发生变化。通信在新线程下进行,而 UI 线程推送和弹出 ProgressDialogScreen。

问题是有时,当响应到来并弹出 ProgressDialogScreen 时,UI 不会改变,但几秒钟后 UI 会改变。如果您在 ProgressDialogScreen 弹出和新 Screen 被推送之间请求,就会出现混乱。第一个最旧的新屏幕被推送,最新的新屏幕被推送。可以观察到这种情况,例如服务器响应错误的请求。这个问题出现在模拟器和设备上。

另一个问题是,有时一个请求会返回两个相同的响应。我能够在模拟器上的日志中看到这两个问题,但我无法在设备上看到这个问题,因为我看不到日志。

编辑:

String utf8Response;
HttpConnection httpConn = null;
try
    httpConn = (HttpConnection) Connector.open(url);
    httpConn.setRequestMethod(HttpConnection.GET);
    httpConn.setRequestProperty("Content-Type", "text/html; charset=UTF8");
    if(sessionIdCookie != null)
        //may throw IOException, if the connection is in the connected state.
        httpConn.setRequestProperty("Cookie", sessionIdCookie);
    
catch (Exception e) 
    //...


try
    httpConn.getResponseCode();
    return httpConn;
catch (IOException e) 
    // ...

byte[] responseStr = new byte[(int)httpConn.getLength()];
DataInputStream strm = httpConn.openDataInputStream();
strm.readFully(responseStr);
try
    strm.close();
catch (IOException e) 
    // ....

utf8Response = new String(responseStr, "UTF-8");

如果这段代码运行成功,则这段代码运行并推送新屏幕:

UiApplication.getUiApplication().invokeLater(new Runnable() 
    public void run() 
       Vector accounts = Parser.parse(utf8Response,Parser.ACCOUNTS);
       if (accounts.size() == 0)
           DialogBox.inform(Account.NO_DEPOSIT);
           return;
       
       currentScreen = new AccountListScreen(accounts);
       changeScreen(null,currentScreen);
    
);

public void changeScreen(final AbstractScreen currentScreen,final AbstractScreen nextScreen) 
    if (currentScreen != null) 
        UiApplication.getUiApplication().popScreen(currentScreen);
    if (nextScreen != null)
        UiApplication.getUiApplication().pushScreen(nextScreen);

EDITv2:

private static void progress(final Stoppable runThis, String text,boolean cancelable) 
    progress = new ProgressBar(runThis, text,cancelable);
    Thread threadToRun = new Thread() 
        public void run() 
            UiApplication.getUiApplication().invokeLater(new Runnable() 
                public void run() 
                    try
                        UiApplication.getUiApplication().pushScreen(progress);
                    catch(Exception e)
                        Logger.log(e);
                    
                
            );
            try 
                runThis.run();
             catch (Throwable t) 
                t.printStackTrace();
            
            UiApplication.getUiApplication().invokeLater(new Runnable() 
                 public void run() 
                    try 
                        UiApplication.getUiApplication().popScreen(progress);
                     catch (Exception e)  
                 
            );
        
   ;
   threadToRun.start();

顺便说一下,ProgressBar 是从 net.rim.device.api.ui.container.PopupScreen 扩展而来的,Stoppable 是从 Runnable 扩展而来的

【问题讨论】:

请显示您的实际代码。 您可以在问题面板中找到我在上面使用的一段代码。 我没有看到弹出窗口的代码。请张贴。 invokeLater 如果您不介意它何时执行(例如:如果它是任务中的最后一件事也可以)。否则试试invokeAndWait 上面提供了弹出代码。你是说如果我使用invokeAndWait而不是invokeLater,第一个问题就没有了? 您需要同步您的用户操作(因此一次只能处理一个请求)或者您需要在流程中实施某种签入(例如,如果旧流程取消,则取消新流程已经接近完成)。不确定我是否理解了这个问题..但您的问题似乎是您的网络和解析任务需要一些时间,如果用户从某种 onClick 触发 2 个或更多线程,您将有更多线程完成并推送屏幕.. . ? 【参考方案1】:

我更喜欢在新屏幕准备好并推送后弹出进度条。这样请求和响应之间就不会再有新的请求了。

【讨论】:

【参考方案2】:

为什么不这样做:

private static void progress(final Stoppable runThis, String text,boolean cancelable) 
    progress = new ProgressBar(runThis, text,cancelable);
    UiApplication.getUiApplication().pushScreen(progress);
    [...]

【讨论】:

我不明白这将如何成为解决问题的好方法。你能解释一下吗?【参考方案3】:

似乎您正在对 UI 线程进行解析。请从 ui 线程中删除 Vector accounts = Parser.parse(utf8Response,Parser.ACCOUNTS); 并在单独的线程中执行。

【讨论】:

我认为这个问题并不像我想的那么清楚。有时会出现问题,因此我们应该查看线程人员,对吗?

以上是关于黑莓多线程问题的主要内容,如果未能解决你的问题,请参考以下文章

使用 Phonegap/WebWorks 的黑莓中线程过多

QFuture 无法为位于不同线程中的父级创建子级

python多线程和多线程问题

27多线程(多线程的三种实现方式Thread线程类的常见方法线程安全问题)

27多线程(多线程的三种实现方式Thread线程类的常见方法线程安全问题)

c++多线程问题