2011-02-26 6 views
1

나는 샘플을 재생/녹음하는 오디오 앱을 가지고 있습니다. UI에 진행 막대를 넣었지만 샘플을 재생할 때 막대가 움직이지 않거나 샘플이 증가하는 것처럼 보입니다. 내가 어떻게 움직일 수 있니?진행률 막대가 없습니다

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

하칸이 제안했듯이 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 나는 스팀 모드에서 정적 모드로 바 꾸었습니다. 또한 트랙에서 재생을 호출하기 전에 트랙에 데이터를 기록했습니다. 진행률 표시 줄 업데이트를 처리하는 실행 파일에서 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 안녕하세요, 내 처리기 내 UI 스레드 개인 필드가 있지만 atill 작동하지 않습니다. mhandler.sendMessage 및 mHandler.post (new Runnable()는 핸들러를 통해 UI 스레드를 업데이트) 동일한 작업을 수행하지 않아야합니까? 나는 progressbar가 audiotrack 클래스와 같은 스트리밍과 잘 작동하기 전에 읽었습니다. 어떤 아이디어, 감사합니다 – turtleboy

+0

@turtleboy 나는 당신이 옳다고 생각하는데, 빠른 구글에서 보면 AudioTrack # write()가 버퍼에 데이터를 가지고있는 동안 블록하는 것처럼 보인다. –

+0

@ dave.c 멋지다, 내가 들여다 볼 수있는 제안이있어? – turtleboy

0

다른 스레드를 통하지 않고 UI 스레드 (기본 활동 클래스 스레드)의 진행률 막대를 업데이트해야합니다. UI thread로 Handler를 작성해, 다른 thread에 의해이 Handler에 메세지를 송신 할 필요가 있습니다. 안드로이드는 create a ProgressDialog 일 때 이것을 예로들 수 있습니다. 예제와 함께 내 답변을 설명하는 "두 번째 스레드가있는 예제 ProgressDialog"아래 부분을 확장하십시오.

1

AsyncTask 스레드 및 처리기로 저글링을 사용하는 것이 좋습니다. 그것은 필요한 스레드와 핸들러 메소드를 포함합니다. onProgressUpdate은 (publishProgress 호 이후에) 호출 된 UI 스레드이므로 진행률 막대를 successfuly 업데이트 할 수 있습니다.

관련 문제