02-09-2010 04:24 PM
In my application, what I would like is to display a Dialog box while the application is fetching data from a web server. What I find is that the dialog is not displayed until the data fetching is complete. Not sure what I'm doing wrong, but here are snippets of my code. Suggestions are much appreciated.
public class HomeScreen extends MainScreen {
private ImageScreen imageScreen;
private MenuItem viewImage = new MenuItem("View Image",100,10) {
public void run() {
imageScreen = new ImageScreen();
UiApplication.getUiApplication().pushScreen(imageS creen);
imageScreen.getImage();
}
};
}
public class ImageScreen extends MainScreen {
private Dialog statusDlg;
public ImageScreen() {
statusDlg = new Dialog("Loading...",null,null,0,icon);
// some other initializations here
}
public void getImage() throws Exception {
statusDlg.show();
// create the connection...
HttpConnection conn = (HttpConnection) Connector.open(URL,Connector.READ_WRITE, true);
conn.setRequestMethod(HttpConnection.POST);
// set paramters and write out requests here
.
.
.
// open input stream to get response from server
InputStream in = conn.openInputStream();
// process the response
processResponse(conn.getResponseCode(), in);
// close everything out
.
.
}
public void processResponse(final int HTTPResponseCode, final InputStream inputStream)
{
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run()
{
statusDlg.close();
// process response here
.
.
.
}
});
}
}
What I expect to see is an empty screen with a pop up Dialog indicating that the data is "Loading..." while imageScreen.getImage() gets executed (I purposely added latency in my HTTP response to simulate network latency). But instead, I see that the application remains on the current screen (HomeScreen) while the data is being fetched. Once the data is fetched, the new screen (ImageScreen) is displayed and the dialog pops up for a split second.
I hope this makes sense. I can further clarify, otherwise.
Solved! Go to Solution.
02-09-2010 05:22 PM
This is because you are performing the blocking network I/O operation on the event thread (aka UI thread). The getImage method is invoked on the event thread and this method invokes the blocking network I/O operation. After the UI event that caused the getImage method to be invoked is processed, the event thread starts processing next events, one of which tells the OS to display your popup. This, obvsiouly, doesn't happen until getImage() terminates.
What getImage() should probably be doing is offloading the network I/O into another thread (for example, by starting a new thread).
02-11-2010 12:58 AM
Hey!
Take a look at http://supportforums.blackberry.com/t5/Java-Develo
see you!
02-11-2010 10:20 AM
just search the forum a bit more, this question and solutions to it have been posted multiple times already
02-11-2010 01:50 PM
Thanks klyubin for the explanation.
Per your suggestion, I spun off a thread to run the network I/O operations as shown below. I do see the dialog popup. However, things seem to hang when I open the inputstream to get the http response (in = conn.openInputStream). I ran this under debug mode and didn't see any exception being thrown. What seems to be going on here?
public void getImage() {
statusDlg.show();
Thread t = new Thread(new Runnable(){
public void run(){
try {
sendHttpRequest();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
t.start();
}
public void sendHttpRequest() throws Exception {
// create the connection...
HttpConnection conn = (HttpConnection) Connector.open(URL,Connector.READ_WRITE, true);
conn.setRequestMethod(HttpConnection.POST);
// set paramters and write out requests here
.
.
.
// open input stream to get response from server
InputStream in = conn.openInputStream();
// close pop-up dialog
statusDlg.close();
// process the response
processResponse(conn.getResponseCode(), in);
// close everything out
.
.
}
02-11-2010 01:54 PM
What do you mean with "hang"? Where exactly does your code block (I would guess it blocks while waiting for a response, i.e., at the openInputStream() line)? Are you sure that no exceptions are thrown?
02-11-2010 02:00 PM
BTW, is there a list of blocking operations somewhere? It would helpful to know if something needs to be run in its own thread.
02-11-2010 02:04 PM
I may have spoken too soon. I ran the app. again and things are working as expected. Thanks for all your help!