Я разрабатываю приложение 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
, пожалуйста, покажите свой фактический код. –
вы можете найти фрагмент кода, который я использую выше на панели вопросов. –
Я не вижу код для всплывающего окна. Пожалуйста, опубликуйте его. 'invokeLater' отлично, если вы не возражаете, когда он выполняется (например: это нормально, если это последняя вещь в задаче). В противном случае попробуйте 'invokeAndWait'. –