バックグラウンド認識の目的で Asyntask を使用する Android 音声認識システムを開発しています。私のコードは次のとおりです。音声を認識するためにスタートボタンを押すたびに Asyntask の execute を呼び出したかったのですが、Asyntask は 1 回しか実行できないようでした。もう一度呼び出すとクラッシュします。毎回新しい非同期タスクを作成することはお勧めしません。これをインスタンス化すると、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();
}
}
}