如何多次执行Android Asynctask

时间:2013-10-15 06:46:57

标签: android android-asynctask

我正在开发一个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();
        }
    }
}

2 个答案:

答案 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 ..