2012-08-07 27 views
0

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

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

因此,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()方法。

A Runnable类只是一个具有run()方法。您将Runnableloader对象指定给新的Thread,并将其告知start()。这将导致Thread在另一个线程(而不是UI线程)中执行run()方法。只要您不在UI线程上运行网络操作,您的应用程序就不应该显示给用户冻结。

注:在你的原代码,你有这样的:

Main.getUiApplication().invokeLater(new Runnable() { 
     public void run() { 

可能并不需要,在所有。如果代码是从主(UI)线程运行的,那么所做的只是告诉应用程序在UI线程上调用本地定义的run()方法,。你也通过500毫秒延迟。也许你需要那个(?)。但是,如果您只是想立即运行,请删除上面的代码(invokeLater(new Runnable() { public void run() { ...)。只需使用我发布的代码(在本答案的顶部)创建backgroundWorker,然后调用其start()方法。

另外,注意两件事情在我的实现:

我用UiApplication.invokeLater()方法一旦位已经收到。网络操作完成后,必须更新UI。但是不应该在后台线程上完成。所以,你创建一个Runnable至后台线程运行,那么一旦下载完成后,再创建一个Runnable更新UI:

public void run() { 
    imagebitmap[j] = bmp; 
    invalidate(); 
} 

2。因为我创建了另一个Runnable,并在Runnable中使用bmp变量,所以我必须声明它为final参数。编译器要求你这样做。另一种选择是直接使用的情况下锁定,而不是invokeLater()

public void ImageDownloadCompleted(Bitmap bmp) { 
    synchronized(UiApplication.getEventLock()) { 
     imagebitmap[j] = bmp; 
     invalidate(); 
    } 
} 

无论是应为你工作。

+0

好吧,它确实为listfield而不是其他领域。例如,我得到一个位图字段,我显示本地图像,然后在线程中运行下载。之后,我称之为'imagebitmap [j] = bmp; invalidate();'位图字段的图像不会像列表字段中那样改变。 – 2012-08-07 09:42:47

+0

@AlanLai,我想知道如果问题是你正在使用变量'j'来确定'imagebitmap []'中的哪个位图存储。 'Util_BitmapDowloadListener'可能需要传递给索引'j'。你也可以发布那个界面吗? – Nate 2012-08-07 10:31:40

+0

我解决了使用你的代码,包括'同步' – 2012-08-08 06:58:44