当用户强制应用程序退出或转到后台时,我在如何清理我的AsyncTask中使用的内存方面遇到了一些麻烦。
具体来说,我有一个应用程序,它使用AsyncTask记录音频数据并实时绘制信号。对于录制,我使用的是AudioRecord类,它要求您开始录制,然后停止并释放记录对象。我的问题是,我不知道如何停止和释放这个对象。
我已经考虑并尝试过的选择:
onPause、onStop和onDestroy方法中释放对象,但这会导致异常。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();
}
};代码工作的很好,我只是不确定最好的方式,以确保我正确地清理记录对象,并没有泄漏。我的困惑就像当UI线程被暂停或停止时,AsyncTask会发生什么,另外,如果您能够从不同的线程停止AudioRecord对象,那么您就会盯着它。
任何帮助都将不胜感激。
谢谢,
发布于 2013-01-03 19:53:31
不会调用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 pacakge提供的各种API,如Executor、ThreadPoolExecutor和FutureTask。
https://stackoverflow.com/questions/14145726
复制相似问题