2012-07-01 33 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