2012-08-07 26 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