0

AsyncTask当用户强制应用程序退出或进入后台时,我在如何清理我使用的内存时遇到了一些麻烦。

具体来说,我有一个应用程序正在使用AsyncTask记录音频数据并实时绘制信号图。对于录制,我正在使用AudioRecord该类,这需要您开始录制,然后停止并释放录制对象。我的问题是我不知道如何停止和释放这个对象。

我考虑过并尝试过的选项:

  1. onPause在、onStop和方法中停止释放对象onDestroy,但这会导致异常。
  2. onPostExecute在 的方法中停止和释放对象AsyncTask。这个问题是我不确定当用户强制退出应用程序时是否调用过这个方法,因为这个doInBackground方法永远不会完成。我无法找到任何与此相关的文档。

我的AsyncTask样子如下:

        AsyncTask<Void, Void, Void> drawer = new AsyncTask<Void, Void, Void>() {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            recorder.startRecording();
        }

        @Override
        protected Void doInBackground(Void... arg0) {
            while(true) {
                int nRead = 0;
                int offset = 0;

                while(nRead != readSize) {
                    nRead += recorder.read(buffer, offset + nRead, readSize - nRead);
                }

                for(int i = 0; i < readSize; i++) {
                    data[i] = buffer[i];    
                }

                publishProgress();
            }               
        }

        @Override
        protected void onProgressUpdate(Void... arg0) {
            view.setData(data);
            view.invalidate();
        }
    };

该代码效果很好,我只是不确定确保我正确清理记录对象并且根本不泄漏的最佳方法。我的困惑是AsyncTask当 UI 线程暂停或停止时会发生什么,此外,如果您能够停止AudioRecord来自不同线程的对象,您就盯着它看。

任何帮助将不胜感激。
谢谢,

4

1 回答 1

2

OnPostExecute不会被调用,因为你永远不会完成你的后台循环。您需要有一个退出循环的条件。您可以在 UI 中设置一个变量,然后签入后台任务,或者使用取消功能AsyncTask

例如,在您的onPause()方法中,您可以取消任务drawer.cancel(true);

然后,在您的doInBackground循环中,检查任务是否已被取消。

if (isCancelled()) {
   // clean up here
   break;
} else {
  publishProgress();
}

只要您不需要触摸 UI 进行清理,它就可以工作。如果您需要进行 UI 清理,那么您可以覆盖该onCancelled方法。

请注意,对于长时间运行的任务,建议您不要使用AsyncTask. 所以你可能想研究使用线程。从AsyncTask 文档中,

AsyncTasks 最好用于短时间的操作(最多几秒钟)。如果您需要保持线程长时间运行,强烈建议您使用 java.util.concurrent 包提供的各种 API,例如Executor、ThreadPoolExecutor 和 FutureTask。

于 2013-01-03T19:53:31.800 回答