2012-07-01 34 views
1

嗯,我可以啓動線程,當我按下togglebutton到ON,它工作正常,該線程將啓動audiorecord和audiotrack。 但是我不能停止線程,當我把togglebutton關閉...因爲我不能做thread.stop ...我想要做的只是停止audiorecord和audiotrack ...如果有任何方法來啓動/停止他們w/o製作線程也會很好。 此外,因爲我不能停止線程,當我做togglebutton ON - OFF - ON時,它會發生錯誤,因爲無法啓動線程2次。如何停止oncheckedchanged中的線程?

回答

0

線程的stop()方法一直棄用(因爲它固有的不安全)和Java提供了一種替代的方式來停止一個線程。它是一種非常簡單的方法,在這個官方鏈接描述:

http://docs.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html

你嘗試製作isRecording變量全局,然後改變其狀態:

isRecording = false; 

Thread thread; 

Runnable r = new Runnable() { 
public void run() { 
    isRecording = true; 
    android.os.Process 
      .setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); 
    int buffersize = AudioRecord.getMinBufferSize(8000, 
      AudioFormat.CHANNEL_CONFIGURATION_MONO, 
      AudioFormat.ENCODING_PCM_16BIT); 
    arec = new AudioRecord(MediaRecorder.AudioSource.MIC, 11025, 
      AudioFormat.CHANNEL_CONFIGURATION_MONO, 
      AudioFormat.ENCODING_PCM_16BIT, buffersize); 
    int bufferzize = AudioTrack.getMinBufferSize(11025, 
      AudioFormat.CHANNEL_CONFIGURATION_MONO, 
      AudioFormat.ENCODING_PCM_16BIT); 
    atrack = new AudioTrack(AudioManager.STREAM_MUSIC, 11025, 
      AudioFormat.CHANNEL_CONFIGURATION_MONO, 
      AudioFormat.ENCODING_PCM_16BIT, bufferzize, 
      AudioTrack.MODE_STREAM); 
    atrack.setPlaybackRate(11025); 
    byte[] buffer = new byte[buffersize]; 
    if (arec.getState() == AudioRecord.STATE_INITIALIZED) 
     arec.startRecording(); 
    if (atrack.getState() == AudioTrack.STATE_INITIALIZED) 
     atrack.play(); 
    while (isRecording) { 
     arec.read(buffer, 0, buffersize); 
     atrack.write(buffer, 0, buffer.length); 
    } 
} 

}; 

tbs = (ToggleButton) findViewById(R.id.tbS); 
tbs.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 

    public void onCheckedChanged(CompoundButton buttonView, 
      boolean isChecked) { 
     // TODO Auto-generated method stub 
     if (isChecked) { 
      thread = new Thread(r) 
      thread.start(); 
      } else { 
      isRecording = false; 
      thread = null; 
     } 

    } 
}); 
+0

是的,我試過,併發生相同的因爲它不能完全停止線程,所以當我做兩次,有一個錯誤 – user1494252

+0

我我不確定你的程序是如何工作的,因爲你正在使用'CheckedChangeListener'內的'thread'變量,甚至在聲明或初始化之前。我粘貼了一段代碼,也許你想嘗試一下。 –

+0

咋我試過了,這個對你有用嗎?對我來說這是行不通的 – user1494252

0

也許你可以使用一個變量並檢查功能運行,如果它的狀態,這樣的:

tbs = (ToggleButton) findViewById(R.id.tbS); 
    boolean stopThread = false; 
    tbs.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 

    public void onCheckedChanged(CompoundButton buttonView, 
      boolean isChecked) { 
     // TODO Auto-generated method stub 
     if (isChecked) { 

      thread.start(); 
      } else { 
      stopThread = true; 
     } 

    } 
}); 
     Thread thread = new Thread() { 
public void run() { 
    isRecording = true; 
    android.os.Process 
      .setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); 
    int buffersize = AudioRecord.getMinBufferSize(8000, 
      AudioFormat.CHANNEL_CONFIGURATION_MONO, 
      AudioFormat.ENCODING_PCM_16BIT); 
    arec = new AudioRecord(MediaRecorder.AudioSource.MIC, 11025, 
      AudioFormat.CHANNEL_CONFIGURATION_MONO, 
      AudioFormat.ENCODING_PCM_16BIT, buffersize); 
    int bufferzize = AudioTrack.getMinBufferSize(11025, 
      AudioFormat.CHANNEL_CONFIGURATION_MONO, 
      AudioFormat.ENCODING_PCM_16BIT); 
    atrack = new AudioTrack(AudioManager.STREAM_MUSIC, 11025, 
      AudioFormat.CHANNEL_CONFIGURATION_MONO, 
      AudioFormat.ENCODING_PCM_16BIT, bufferzize, 
      AudioTrack.MODE_STREAM); 
    atrack.setPlaybackRate(11025); 
    byte[] buffer = new byte[buffersize]; 
    if (arec.getState() == AudioRecord.STATE_INITIALIZED) 
     arec.startRecording(); 
    if (atrack.getState() == AudioTrack.STATE_INITIALIZED) 
     atrack.play(); 
    while (isRecording) { 
     arec.read(buffer, 0, buffersize); 
     atrack.write(buffer, 0, buffer.length); 
    } 

    if(stopThread) 
     return; 
} 

}; 
+0

我已經嘗試過,但沒有工作 – user1494252

+0

我已經做到了,但我想我用一個靜態布爾做到這一點。 – Guillaume

+0

這個doesnt停止線程,所以線程會啓動2次 – user1494252

0

我在這種情況下preffer處理程序。

他們有兩個特點

Handler audioHandler = new Handler(); 

audioHandler.post(startAudio); // Starts the operations 

audioHandler.removeCallbacks(startAudio); //Stops the Operation 

下面的代碼片段會幫助你。

package org.sample; 

import android.app.Activity; 
import android.media.AudioFormat; 
import android.media.AudioManager; 
import android.media.AudioRecord; 
import android.media.AudioTrack; 
import android.media.MediaRecorder; 
import android.os.Bundle; 
import android.os.Handler; 
import android.widget.CompoundButton; 
import android.widget.ToggleButton; 

public class SampleActivity extends Activity { 

    private Handler audioHandler; 
    private Runnable startAudio; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     audioHandler = new Handler(); 

     startAudio = new Runnable() { 

      @Override 
      public void run() { 
       isRecording = true; 
       android.os.Process 
         .setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); 
       int buffersize = AudioRecord.getMinBufferSize(8000, 
         AudioFormat.CHANNEL_CONFIGURATION_MONO, 
         AudioFormat.ENCODING_PCM_16BIT); 
       arec = new AudioRecord(MediaRecorder.AudioSource.MIC, 11025, 
         AudioFormat.CHANNEL_CONFIGURATION_MONO, 
         AudioFormat.ENCODING_PCM_16BIT, buffersize); 
       int bufferzize = AudioTrack.getMinBufferSize(11025, 
         AudioFormat.CHANNEL_CONFIGURATION_MONO, 
         AudioFormat.ENCODING_PCM_16BIT); 
       atrack = new AudioTrack(AudioManager.STREAM_MUSIC, 11025, 
         AudioFormat.CHANNEL_CONFIGURATION_MONO, 
         AudioFormat.ENCODING_PCM_16BIT, bufferzize, 
         AudioTrack.MODE_STREAM); 
       atrack.setPlaybackRate(11025); 
       byte[] buffer = new byte[buffersize]; 
       if (arec.getState() == AudioRecord.STATE_INITIALIZED) 
        arec.startRecording(); 
       if (atrack.getState() == AudioTrack.STATE_INITIALIZED) 
        atrack.play(); 
       while (isRecording) { 
        arec.read(buffer, 0, buffersize); 
        atrack.write(buffer, 0, buffer.length); 
       } 

       audioHandler.post(startAudio); 

      } 
     }; 

     tbs = (ToggleButton) findViewById(R.id.tbS); 
     tbs.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 

      public void onCheckedChanged(CompoundButton buttonView, 
        boolean isChecked) { 
       // TODO Auto-generated method stub 
       if (isChecked) { 
        audioHandler.post(startAudio); 
       } else { 
        audioHandler.removeCallbacks(startAudio); 
       } 

      } 
     }); 

    } 
} 
+0

請問audioHandler.post(startAudio);在run()方法被調用之後? – Ashwin

+0

Yes.it最後在run方法下執行。所以當執行到達run方法結束時,它再次啓動循環。 –

+0

ehmm這不適用於我至少:S的錯誤是,無法獲得音頻輸入源,這並沒有發生之前線程:S – user1494252

0

線程是活動的,只要isRecordingtrue。所以你可以有一個final StringBuilder用來在你需要的時候操作isRecording的值。

final StringBuilder isRecording=new StringBuilder("t"); 
Thread thread = new Thread() { 
      public void run() { 

       android.os.Process 
         .setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); 
       int buffersize = AudioRecord.getMinBufferSize(8000, 
         AudioFormat.CHANNEL_CONFIGURATION_MONO, 
         AudioFormat.ENCODING_PCM_16BIT); 
       arec = new AudioRecord(MediaRecorder.AudioSource.MIC, 11025, 
         AudioFormat.CHANNEL_CONFIGURATION_MONO, 
         AudioFormat.ENCODING_PCM_16BIT, buffersize); 
       int bufferzize = AudioTrack.getMinBufferSize(11025, 
         AudioFormat.CHANNEL_CONFIGURATION_MONO, 
         AudioFormat.ENCODING_PCM_16BIT); 
       atrack = new AudioTrack(AudioManager.STREAM_MUSIC, 11025, 
         AudioFormat.CHANNEL_CONFIGURATION_MONO, 
         AudioFormat.ENCODING_PCM_16BIT, bufferzize, 
         AudioTrack.MODE_STREAM); 
       atrack.setPlaybackRate(11025); 
       byte[] buffer = new byte[buffersize]; 
       if (arec.getState() == AudioRecord.STATE_INITIALIZED) 
        arec.startRecording(); 
       if (atrack.getState() == AudioTrack.STATE_INITIALIZED) 
        atrack.play(); 
       while (isRecording.toString().equals("t")) { 
        arec.read(buffer, 0, buffersize); 
        atrack.write(buffer, 0, buffer.length); 
       } 
      } 

     }; 
    tbs = (ToggleButton) findViewById(R.id.tbS); 
     tbs.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 

      public void onCheckedChanged(CompoundButton buttonView, 
        boolean isChecked) { 
       // TODO Auto-generated method stub 
       if (isChecked) { 
        isRecording.replace(0,0,"t"); 
        thread.start(); 
        } else { 
       isRecording.replace(0,0,"f") 
       } 

      } 
     }); 
+0

isRecording.replace(0,「f」)在這裏它說我需要再放1個數字,比如isRecording.replace(0, ?,「f」)該怎麼辦? – user1494252

+0

也不能停止線程,因爲isRecording隻影響while() – user1494252

+0

@ user1494252:我編輯了替換函數。就你的線程而言,只要while循環運行,線程就會「運行」。所以如果你從while循環中出來,你的線程就結束了嗎? – Ashwin