在线下载图像时黑莓设备挂起

时间:2012-08-07 07:20:53

标签: multithreading networking blackberry

每当我的应用程序进入在线下载图像的布局时,设备将挂起并需要等待下载完成才能移动。

我做了一些研究。他们建议在另一个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;
    }
}
}

我需要帮助,因为我不熟悉网络。

1 个答案:

答案 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();
    }
}

要么适合你。