Every time when my apps went to the layout that download image online, the device will hang and need to wait the download finish only can movable.
I did some researched. They recommend download it in another Thread. However, I not understand how to implement the download function in another Thread.
Here is my code to call the download image function.
Main.getUiApplication().invokeLater(new Runnable() {
public void run() {
for (j = 0; j < imagepath.length; j++) {
if (!imagepath[j].toString().equals("no picture")
&& Config_GlobalFunction.isConnected()) {
loader = new Util_LazyLoader(imagepath[j],
new Util_BitmapDowloadListener() {
public void ImageDownloadCompleted(
Bitmap bmp) {
imagebitmap[j] = bmp;
invalidate();
}
});
loader.run();
}
}
}
}, 500, false);
And the lazyloader
public class Util_LazyLoader implements Runnable {
String url = null;
Util_BitmapDowloadListener listener = null;
public Util_LazyLoader(String url, Util_BitmapDowloadListener listener) {
this.url = url;
this.listener = listener;
}
public void run() {
Bitmap bmpImage = getImageFromWeb(url);
listener.ImageDownloadCompleted(bmpImage);
}
private Bitmap getImageFromWeb(String url) {
HttpConnection connection = null;
InputStream inputStream = null;
EncodedImage bitmap;
byte[] dataArray = null;
try {
connection = (HttpConnection) (new ConnectionFactory())
.getConnection(url + Database_Webservice.ht_params)
.getConnection();
int responseCode = connection.getResponseCode();
if (responseCode == HttpConnection.HTTP_OK) {
inputStream = connection.openDataInputStream();
dataArray = IOUtilities.streamToBytes(inputStream);
}
} catch (Exception ex) {
} finally {
try {
inputStream.close();
connection.close();
} catch (Exception e) {
}
}
if (dataArray != null) {
bitmap = EncodedImage.createEncodedImage(dataArray, 0,
dataArray.length);
return bitmap.getBitmap();
} else {
return null;
}
}
}
I need help on it as I not familiar in networking.
So, the
Util_LazyLoaderis already well written to support background image downloads, because it implements theRunnableinterface. You can start the download like this:instead of directly calling the
loader.run()method yourself.A
Runnableclass is just one that has arun()method. You give yourRunnableloaderobject to a newThreadand tell it tostart(). This will cause thatThreadto execute therun()method in another thread, instead of the UI thread. As long as you don’t run network operations on the UI thread, your app should not appear to the user to be frozen.Note: in your original code, you have this:
You probably don’t need that at all. If that code is being run from the main (UI) thread, then all that’s doing is telling the app to invoke that locally-defined
run()method, also on the UI thread. You do pass a500millisecond delay as well. Maybe you need that (?). If you just want it to run right away, though, get rid of the code above (invokeLater(new Runnable() { public void run() { ...). Just use the code I posted (at the top of this answer) to create thebackgroundWorkerand then call itsstart()method.Also, take note of two things in my implementation:
1. I used the
UiApplication.invokeLater()method once the bitmap has been received. After the network operation completes, the UI must be updated. But that should not be done on the background thread. So, you create aRunnableto run on the background thread, and then once the download is complete, you create anotherRunnableto update the UI:2. Because I create another
Runnable, and use thebmpvariable inside thatRunnable, I must declare it as afinalparameter. The compiler requires you to do that. Another option would be to use the event lock directly, instead ofinvokeLater():Either should work for you.