每当我的应用程序进入在线下载图像的布局时,设备将挂起并需要等待下载完成才能移动。
我做了一些研究。他们建议在另一个Thread
下载它。但是,我不明白如何在另一个Thread
中实现下载功能。
这是我调用下载图像功能的代码。
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);
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;
}
}
}
我需要帮助,因为我不熟悉网络。
答案 0 :(得分:1)
因此,Util_LazyLoader
已经编写好以支持后台映像下载,因为它实现了Runnable
接口。您可以像这样开始下载:
Util_LazyLoader loader =
new Util_LazyLoader(imagepath[j],
new Util_BitmapDowloadListener() {
public void ImageDownloadCompleted(final Bitmap bmp) {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
imagebitmap[j] = bmp;
invalidate();
}
});
}
});
Thread backgroundWorker = new Thread(loader);
backgroundWorker.start();
而不是自己直接调用loader.run()
方法。
Runnable
类只是具有run()
方法的类。您将Runnable
loader
个对象提供给新的Thread
并告诉start()
。这将导致Thread
在另一个线程中执行run()
方法,而不是UI线程。只要您不在UI线程上运行网络操作,您的应用就不会对用户显示为冻结。
注意:,您有:
Main.getUiApplication().invokeLater(new Runnable() {
public void run() {
你可能根本不需要它。如果该代码是从主(UI)线程运行的,那么所有正在做的就是告诉应用程序在UI线程上调用本地定义的run()
方法,也。你也传递了500
毫秒的延迟。也许你需要那个(?)。但是,如果您只是希望它立即运行,请删除上面的代码(invokeLater(new Runnable() { public void run() { ...
)。只需使用我发布的代码(在此答案的顶部)创建backgroundWorker
,然后调用其start()
方法。
另外,请注意我的实现中的两件事:
1。一旦收到位图,我就使用了UiApplication.invokeLater()
方法。网络操作完成后,必须更新UI。但不应该在后台线程上完成。因此,您创建一个Runnable
以在后台线程上运行,然后在下载完成后,您创建另一个Runnable
来更新UI:
public void run() {
imagebitmap[j] = bmp;
invalidate();
}
2。因为我创建了另一个Runnable
,并使用bmp
内的Runnable
变量,我必须将其声明为final
参数。编译器要求您这样做。另一种选择是直接使用事件锁,而不是invokeLater()
:
public void ImageDownloadCompleted(Bitmap bmp) {
synchronized(UiApplication.getEventLock()) {
imagebitmap[j] = bmp;
invalidate();
}
}
要么适合你。