我正在开发一个Android语音识别系统,它使用Asyntask进行背景识别。我的代码如下。每当我按下开始按钮识别我的语音时,我想调用Asyntask的执行,但似乎Asyntask只能被执行一次。如果我再说一次,那就会崩溃。请不要建议每次都创建一个新的Asyntask,因为实例化它会导致UI线程跳过数百帧,并且会使用户体验变得非常慢。
我该怎么做才能解决这个问题?
public class PocketSphinxAndroidDemo extends Activity {
private class RecognitionTask
extends AsyncTask<AudioRecord, Void, Hypothesis> {
Decoder decoder;
Config config;
public RecognitionTask() {
Config config = Decoder.defaultConfig();
decoder = new Decoder(config);
}
protected void doInBackground(AudioRecord... recorder) {
int nread;
short[] buf = new short[1024];
decoder.startUtt(null);
while ((nread = recorder[0].read(buf, 0, buf.length)) > 0)
decoder.processRaw(buf, nread, false, false);
decoder.endUtt();
return decoder.hyp();
}
protected void onPostExecute(Hypothesis hypothesis) {
if (null != hypothesis)
speechResult.append("\n" + hypothesis.getHypstr());
else
speechResult.append("\n<no speech>");
}
}
private static final int SAMPLE_RATE = 8000;
static {
System.loadLibrary("pocketsphinx_jni");
}
private TextView speechResult;
private AudioRecord recorder;
private RecognitionTask recTask;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
speechResult = (TextView) findViewById(R.id.SpeechResult);
recorder = new AudioRecord(MediaRecorder.AudioSource.VOICE_RECOGNITION,
SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT, 8192);
recTask = new RecognitionTask();
}
public void onToggleRecognition(View view) {
if (!(view instanceof ToggleButton))
return;
if (((ToggleButton) view).isChecked()) {
recorder.startRecording();
recTask.execute(recorder);
} else {
recorder.stop();
}
}
}
答案 0 :(得分:1)
你可以使用Raghunandan推荐的Looper和Thread,而且你得到的崩溃可能是你使用相同的对象来执行你的AsyncTask。如果要再次调用异步任务,则必须创建一个新对象,然后执行AsyncTask。
喜欢这个
new MyAsyncTask().execute("");
答案 1 :(得分:0)
是的..按照每个Android文档,它只能执行一次.. http://developer.android.com/reference/android/os/AsyncTask.html。从我的exp开始,在postexecute
方法之后,它将被取消。所以像
new RecognitionTask().execute(recorder)
并在activity ...中创建那些Decoder,Config变量并将其显式传递给task ..