2011-02-26 101 views
1

我有一個播放/記錄樣本的音頻應用程序。我已經在用戶界面上放置了一個進度條,但是當播放該示例時,該欄不會移動或似乎隨着示例而增加。我如何讓它移動?progressbar not moving

mProgress = (ProgressBar) findViewById(R.id.progressBar1); 
      // final long trackDuration = (musicLength/44100)*1000; // track duration in millisec 

      // Start lengthy operation in a background thread 
      new Thread(new Runnable() { 
       public void run() { 
        //Log.i("music length = ", trackDuration+""); 

        while (mProgressStatus < musicLength) { 
         mProgressStatus = audioTrack.write(music, 0, musicLength); 

         // Update the progress bar 
         mHandler.post(new Runnable() { 
          public void run() { 
           mProgress.setProgress(mProgressStatus); 

          } 
         }); 
        } 
       } 
      }).start(); 

回答

0

正如Hakan所說,您需要在UI線程中執行所有UI更新。既然你已經有了Handler,你只需要重寫handleMessage()方法並在那裏執行你的UI更新。你的代碼會變成類似於:

private static final int PROGRESS_UPDATE = 0; 
... 
mProgress = (ProgressBar) findViewById(R.id.progressBar1); 
// final long trackDuration = (musicLength/44100)*1000; // track duration in millisec 

// Start lengthy operation in a background thread 
new Thread(new Runnable() { 
    public void run() { 
     //Log.i("music length = ", trackDuration+""); 

     while (mProgressStatus < musicLength) { 
      mProgressStatus = audioTrack.write(music, 0, musicLength); 

      // Update the progress bar 
      Message msg = Message.obtain(); 
      msg.what = PROGRESS_UPDATE; 
      msg.arg1 = mProgressStatus; 
      mHandler.sendMessage(msg); 
     } 
    } 
}).start(); 
... 
Handler mHandler = new Handler(){ 
    @Override 
    public void handleMessage(Message msg) { 
     switch(msg.what){ 
     case PROGRESS_UPDATE: 
      mProgress.setProgress(msg.arg1); 
      break; 
     default: 
      Log.e("MyTag","Unsupported message type"); 
      break; 
     } 
    } 
} 

好的,謝謝你的dave.c.我已經從蒸汽模式轉換爲靜態模式。在跟蹤賽道上的賽道之前,我還將數據寫入賽道。我在可處理進度條更新的runnable中調用play。應用程序將播放音頻樣本,但進度條仍不會移動。我將發佈下面顯示修正的代碼。爲什麼進度條沒有移動的任何想法?

// Get the length of the audio stored in the file (16 bit so 2 bytes per short) 
     // and create a short array to store the recorded audio. 
     musicLength = (int)(file.length()/2); 
     final short[] music = new short[musicLength]; 
     Log.i("filename length", file.length()+""+file.getName()); 

     try { 



     // Create a DataInputStream to read the audio data back from the saved file. 
     InputStream is = new FileInputStream(file); 
     BufferedInputStream bis = new BufferedInputStream(is); 
     DataInputStream dis = new DataInputStream(bis); 

     // Read the file into the music array. 
     int i = 0; 
     while (dis.available() > 0) { 
     //music[musicLength-1-i] = dis.readShort(); 
      music[i] = dis.readShort(); 

     i++; 
     } 
     Log.i("buffer with "+ file.getName(), music.length+" passed in from array"); 

     // Close the input streams. 
     dis.close(); 


     // Create a new AudioTrack object using the same parameters as the AudioRecord 
     // object used to create the file. 
     audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 
     44100, 
     AudioFormat.CHANNEL_CONFIGURATION_MONO, 
     AudioFormat.ENCODING_PCM_16BIT, 
     musicLength, 
     AudioTrack.MODE_STATIC); 

     Log.i("audio instance = ", ""+audioTrack.getState()); 

     // Start playback 
     //audioTrack.play(); 






      mProgress = (ProgressBar) findViewById(R.id.progressBar1); 
      // final long trackDuration = (musicLength/44100)*1000; // track duration in millisec 

      // Start lengthy operation in a background thread 
      new Thread(new Runnable() { 
       public void run() { 
        //Log.i("music length = ", trackDuration+""); 

        while (mProgressStatus < musicLength) { 

         mProgressStatus = audioTrack.write(music, 0, musicLength); 

         // Update the progress bar 
         mHandler.post(new Runnable() { 
          public void run() { 
           audioTrack.play(); 
           mProgress.setProgress(mProgressStatus); 


          } 
         }); 

         Message msg = Message.obtain(); 
         msg.what = PROGRESS; 
         msg.arg1 = mProgressStatus; 
         mHandler.sendMessage(msg); 





        } 
       } 
      }).start(); 

      mHandler = new Handler(){ 
        @Override 
        public void handleMessage(Message msg) { 
         switch(msg.what){ 
         case PROGRESS: 
          mProgress.setProgress(msg.arg1); 

          break; 
         default: 
         Log.e("MyTag","Unsupported message type"); 
          break; 
         } 

        } 

      }; 




     } catch (Exception e) { 
      e.printStackTrace(); 
     Log.e("AudioTrack","Playback Failed"); 
     } 

    } 
+0

@ dave.c嗨,我的Handler是我的UI線程中的一個私有字段,但它仍然無法工作。不應該mhandler.sendMessage和mHandler.post(新的Runnable()做同樣的事情,(通過處理程序更新ui線程)?我發誓我已經閱讀過,進度條沒有任何工作良好的流如audiotrack類我使用pcm文件播放任何想法,謝謝 – turtleboy 2011-02-27 07:39:48

+0

@turtleboy我認爲你是對的從快速谷歌似乎'AudioTrack#write()'阻塞,而它的緩衝區中有數據,因此你不會去在寫入'write'之後發現任何代碼 – 2011-02-27 12:44:23

+0

@ dave.c好的,你有什麼建議可以看看嗎 – turtleboy 2011-02-27 18:02:12

0

你需要更新通過其他線程在UI線程進度條(這是主要的活動課線程),而不是。你需要在UI線程中創建一個Handler,並通過其他線程向這個Handler發送消息。 Android有一個例子,當他們create a ProgressDialog。請確保展開底部顯示「使用第二個線程的示例ProgressDialog」的部分,因爲這解釋了我在示例中的答案。

1

建議使用AsyncTask與主題和處理程序混雜在一起玩。它包含需要的線程和處理程序方法。 onProgressUpdate是在UI線程中調用的(每調用一次publishProgress之後),以便它可以成功更新您的進度條。