Reputation: 1554
I am developing an android speech recognition system that uses Asyntask for background recognition purpose. My code is as following. I wanted to call the Asyntask's execute everytime I pushed the start button to recognize my speech, but it seemed the Asyntask can only be exectued once. There's a crash if I call it another time. Please don't suggest create a new Asyntask each time because instantiating it causes the UI thread to skip hundreds of frames, and it made the user experience awkwardly slow.
What can I do to fix this problem?
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();
}
}
}
Upvotes: 0
Views: 159
Reputation: 1640
yes..as per android doc it can be executed only once..http://developer.android.com/reference/android/os/AsyncTask.html . From my exp,after postexecute
method it will be cancelled.so use like
new RecognitionTask().execute(recorder)
and create those Decoder,Config variables inside activity..and pass it explicitly to task..
Upvotes: 0
Reputation: 6925
You can use a Looper and Thread as recommended by Raghunandan, Moreover the crash you were getting is may be you are using the same object to execute your AsyncTask. If you want to call your async task again you must create a new object and then execute your AsyncTask.
Like this
new MyAsyncTask().execute("");
Upvotes: 1