2012-01-11 2 views
0

Я разрабатываю приложение BlackBerry, которое общается с сервером по HTTP-запросам (javax.microedition.io.HttpConnection). На устройстве пользователь нажимает на некоторые элементы пользовательского интерфейса, и устройство отправляет запросы на сервер, когда приходит ответ, изменяется пользовательский интерфейс. Связь происходит под новым потоком, в то время как поток пользовательского интерфейса толкает и выдает ProgressDialogScreen.Blackberry multi threading issue

Проблема заключается в том, что при возникновении ответа и выходе из режима ProgressDialogScreen пользовательский интерфейс не изменяется, но после пары секунд пользовательский интерфейс изменяется. Если вы запросили промежуток времени, когда вызывается ProgressDialogScreen, и когда новый экран нажат, наступает беспорядок. Первый старейший новый экран нажат, и новый новый экран нажат. И эту ситуацию можно наблюдать, как сервер, отвечающий за неправильные запросы. Эти проблемы возникают на тренажере и устройстве.

Другая проблема, иногда два одинаковых ответа возвращаются для одного запроса. Я смог увидеть эти две проблемы на симуляторе в журналах, но я не смог увидеть эту проблему на устройстве, так как я не вижу журналы.

EDIT:

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

+0

, пожалуйста, покажите свой фактический код. –

+1

вы можете найти фрагмент кода, который я использую выше на панели вопросов. –

+0

Я не вижу код для всплывающего окна. Пожалуйста, опубликуйте его. 'invokeLater' отлично, если вы не возражаете, когда он выполняется (например: это нормально, если это последняя вещь в задаче). В противном случае попробуйте 'invokeAndWait'. –

ответ

1

Я предпочел, чтобы индикатор прогресса появлялся после того, как новый экран подготовлен и нажат. Таким образом, новый запрос между запросом и ответом не будет.

0

Почему бы не сделать:

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

Я не понимаю, как это будет хорошим решением проблем. Не могли бы вы немного объяснить. –

0

Похоже, вы разбираете на UI Thread. Удалите Vector accounts = Parser.parse(utf8Response,Parser.ACCOUNTS); из нити ui и сделайте это в отдельной теме.

+0

Я думаю, что вопрос не так ясен, как я думал. Иногда возникает проблема, поэтому мы должны смотреть на поточно-кадровый персонал, не так ли? –