嗯,我可以啓動線程,當我按下togglebutton到ON,它工作正常,該線程將啓動audiorecord和audiotrack。 但是我不能停止線程,當我把togglebutton關閉...因爲我不能做thread.stop ...我想要做的只是停止audiorecord和audiotrack ...如果有任何方法來啓動/停止他們w/o製作線程也會很好。 此外,因爲我不能停止線程,當我做togglebutton ON - OFF - ON時,它會發生錯誤,因爲無法啓動線程2次。如何停止oncheckedchanged中的線程?
回答
線程的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;
}
}
});
也許你可以使用一個變量並檢查功能運行,如果它的狀態,這樣的:
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;
}
};
我已經嘗試過,但沒有工作 – user1494252
我已經做到了,但我想我用一個靜態布爾做到這一點。 – Guillaume
這個doesnt停止線程,所以線程會啓動2次 – user1494252
我在這種情況下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);
}
}
});
}
}
請問audioHandler.post(startAudio);在run()方法被調用之後? – Ashwin
Yes.it最後在run方法下執行。所以當執行到達run方法結束時,它再次啓動循環。 –
ehmm這不適用於我至少:S的錯誤是,無法獲得音頻輸入源,這並沒有發生之前線程:S – user1494252
線程是活動的,只要isRecording
是true
。所以你可以有一個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")
}
}
});
isRecording.replace(0,「f」)在這裏它說我需要再放1個數字,比如isRecording.replace(0, ?,「f」)該怎麼辦? – user1494252
也不能停止線程,因爲isRecording隻影響while() – user1494252
@ user1494252:我編輯了替換函數。就你的線程而言,只要while循環運行,線程就會「運行」。所以如果你從while循環中出來,你的線程就結束了嗎? – Ashwin
- 1. 如何停止線程當Tomcat停止
- 2. 如何在主線程停止/暫停線程/ Activity在android中暫停/停止?
- 3. 如何停止線程?
- 4. 如何停止Java線程?
- 5. 如何停止線程
- 6. 如何停止線程python
- 7. 如何停止Django線程
- 8. 如何停止線程?
- 9. 如何停止Java線程?
- 10. 如何停止wxpython中的線程?
- 11. 如何停止Android中的線程?
- 12. 如何停止Java中的線程?
- 13. 如何停止python中的線程
- 14. 如何停止android中的ASyncTask線程
- 15. 如何停止pyobjc中的線程
- 16. Java中,如何停止線程
- 17. 如何在Java中停止線程?
- 18. 如何在Java中停止線程
- 19. 如何在android中停止此線程?
- 20. 如何在Android中停止線程?
- 21. Java:如何中斷/停止線程?
- 22. 如何在android中停止asynctask線程?
- 23. 如何讓TcpClient在線程中停止?
- 24. 停止python中的線程
- 25. 停止線程
- 26. 停止線程
- 27. 停止線程
- 28. 如何停止MFC中的主線程和等待子線程
- 29. 如何停止線程池中的線程
- 30. 在python3中停止線程
是的,我試過,併發生相同的因爲它不能完全停止線程,所以當我做兩次,有一個錯誤 – user1494252
我我不確定你的程序是如何工作的,因爲你正在使用'CheckedChangeListener'內的'thread'變量,甚至在聲明或初始化之前。我粘貼了一段代碼,也許你想嘗試一下。 –
咋我試過了,這個對你有用嗎?對我來說這是行不通的 – user1494252