Daniel
Daniel

Reputation: 1554

How to Execute Android Asyntask several times

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

Answers (2)

Manivannan
Manivannan

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

Jitender Dev
Jitender Dev

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

Related Questions