2011-07-14 4 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)の3つにハッピングされていると思いますdと何らかの理由でこれが関係しており、なぜ画面を更新することができないのかが関係しています。どんな助けでも大歓迎です。

P.S. Androidは一般的に私の家であり、ブラックベリーではありません。私が明白でなければならないものを見落としてしまった場合は、ごめんなさい。/

答えて

2

私はいくつかの問題があります。 'downloadVideo()'の後のコードは、ダウンロードが同期して起こったとみなされているようです。ダウンロードがバックグラウンドで行われるようにするためには、ダウンロードの完了を処理する別の方法を設定する必要があります。現在、ビデオ再生コードは、ダウンロードスレッドが開始された直後に実行されます。

また、1kのダウンロードごとにUIイベントロックを取得しています。これはビデオであるため、私はマルチメガバイトのダウンロードを想定しています。つまり、ロックを何千回も取得してリリースしています。ダウンロードメーターには100種類の異なる値しかないため、これはほとんど意味がありません。そのため、ほとんど同じ値で更新しています。最も簡単な修正は、モデルに送信された最後の値を追跡することです。変更されていない場合は、値を取得または更新しないでください。

一般に、キュー管理がないため、UIロックを直接取得したくありません。だから私はUIを更新する必要があるすべてのコードのinvokeLaterを使用します。これには、invokeLaterコードが順番に発生するという素晴らしい特性があります。このコードは、invokeLaterに直接変更した場合のように、キューをオーバーランさせることができます。この問題を回避するには、プログレスメーター更新がキューに登録されているかどうかを追跡する別の変数を設定する必要があります。そうであれば、それ以上待ち行列に入れないでください。

+0

あなたは正しい方向に向かいます。それは今働いている。私のために働いたコードを少し投稿します。ありがとう、トン! – FoamyGuy

関連する問題