2011-07-14 82 views
1

我正在爲將要下載文件的黑莓應用程序工作。我想在此下載過程中顯示進度條。我已經嘗試了GaugeField和ProgressIndicatorView的每個組合,但我沒有得到任何結果。我的下載正在進行,但進度條永遠不會在屏幕上更新。實際上,在我開始嘗試進度條之前,我試圖簡單地使用TextField並使用當前下載完成的百分比進行更新,而且我也沒有這種方式。下載期間黑莓進度條

這是我的屏幕裏:

view = new ProgressIndicatorView(0); 
    model = new ProgressIndicatorModel(0, 100, 0); 
    controller = new ProgressIndicatorController(); 


    model.setController(controller); 
    view.setModel(model); 
    view.setController(controller);   
    controller.setModel(model); 
    controller.setView(view); 

    view.setLabel("Percent completion"); 
    view.createProgressBar(Field.FIELD_HCENTER);  

    add(view); 

    UiApplication.getUiApplication().invokeLater(new Runnable() 
    { 
     public void run() 
     { 
      downloadVideo(); 
      initializeMedia();     

      // If initialization was successful... 
      if(_videoField != null) 
      {      
       createUI();     

       updateVideoSize(); 

       try { 
        _player.start(); 

       } catch (MediaException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
        ScreenSaverActivity.errorDialog("MEDIA EXCEPTION: "+e.toString()); 
       } 
      } 
      else 
      { 
       _statusField.setText("Error: Could not load media"); 
      } 
     } 
    });      

downloadVideo()方法:

private void downloadVideo(){ 

    DownloadThread _dlThread = new DownloadThread(); 

    _dlThread.start(); 

} 

DownloadThread類:

class DownloadThread extends Thread { 
    public void run(){ 

     try { 
      HttpConnection httpConn; 
      httpConn = (HttpConnection)Connector.open("http://url/to/myMovie.mp4"); 
      InputStream is = httpConn.openInputStream(); 

      String fName = "file:///store/BlackBerry/videos/myMovie.mp4"; 


      FileConnection fconn = (FileConnection) Connector.open(fName, Connector.READ_WRITE); 
      if (!fconn.exists()) 
       fconn.create(); 

      OutputStream os = fconn.openOutputStream(); 
      long lengthOfFile = httpConn.getLength(); 
      int total = 0; 
      int count; 
      byte data[] = new byte[1024]; 
      while ((count = is.read(data)) != -1) { 
       //I have tried this line outside of synchronized too, with no luck 
       synchronized(Application.getEventLock()) { 
        EmbeddedMediaScreen.this.model.setValue((int)(total*100/lengthOfFile)); 
       } 

       total += count; 
       //write this chunk 
       os.write(data, 0, count); 
      } 
      os.flush(); 
      os.close(); 
     } catch (IOException e) { 
      ScreenSaverActivity.errorDialog(e.toString()); 
      e.printStackTrace(); 
     } 
    } 
} 

雖然我的應用程序是做下載該設備無法響應,所以我猜測我的麻煩是下載工作正在主要(UI)上進行d出於某種原因,這與我爲什麼無法通過進度更新屏幕有關。任何幫助將不勝感激。

P.S. Android通常是我的家,而不是黑莓,對不起,如果我忽略了一些應該是顯而易見的東西=/

回答

2

我看到一些問題。它看起來像'downloadVideo()'後的代碼假定下載同步發生。由於您希望下載發生在後臺,因此您需要設置一個單獨的方法來處理完成下載。現在您的視頻播放代碼在下載線程啓動後立即執行。

此外,您正在獲取每1k下載的UI事件鎖定。由於這是一個視頻,我假設有一個多兆字節的下載,這意味着您正在獲取並釋放該鎖定數千次。這沒什麼意義,部分原因是下載表只有100個不同的值,所以你主要用相同的值更新它。最簡單的方法是跟蹤發送給模型的最後一個值。如果不變,則不要獲取或更新該值。

一般來說,我不喜歡直接獲取UI鎖,因爲沒有隊列管理。所以我使用invokeLater來處理需要更新UI的所有代碼。這具有invokeLater代碼順序發生的優良屬性。您可以溢出隊列,因爲如果直接將其更改爲invokeLater,此代碼會執行此操作。爲了避免這個問題,你必須設置另一個變量來跟蹤你是否有進度計更新排隊。如果是這樣,不要排隊工作。

+0

你讓我朝着正確的方向前進。它正在工作。將稍後發佈適用於我的代碼。萬分感謝! – FoamyGuy