我每隔100毫秒从一个android CountDownTimer更新一个进度条(使用setProgress())。出于某种原因,每当计时器运行时,在android内存图中,似乎存在内存泄漏(稳定增加)。关于为什么会发生这种情况的任何想法?
final int waitTime = Integer.parseInt(PreferenceManager.getDefaultSharedPreferences(getApplicationContext())
.getString("answer_view_time", "2000"));
final int countFrom = timerWidget.getProgress();
CountDownTimer answerTimer = new CountDownTimer(waitTime, 100) {
@Override
public void onTick(long millisUntilFinished) {
//count up the time for the user to see his answer from where the timer had just left off
timerWidget.setProgress(countFrom +(int) ( ( ( (waitTime - millisUntilFinished) ) / (float) waitTime )
* (timerWidget.getMax() - countFrom) ) );
}
@Override
public void onFinish() {
mQuiz.next();
setQuestion(mQuiz.getCurrent());
btn1.setEnabled(true);
btn2.setEnabled(true);
btn3.setEnabled(true);
btn4.setEnabled(true);
findViewById(R.id.main_conteiner).setBackgroundDrawable(getResources().getDrawable(R.drawable.background_colored));
}
}.start();
这在timerWidget.setProgress(...)中泄漏;线。如果我发表评论,泄漏就会停止。
更新 我找不到任何理由发生这种情况。即使在一个活动中,当通过循环更新进度条时,似乎存在内存泄漏。也许这是Android本身的一个错误?我在联想设备上使用Android 5.1。
答案 0 :(得分:2)
您遇到的一个问题是您的匿名CountDownTimer类具有对其声明的类的引用(变量countFrom和waitTime)。这意味着只要CountDownTimer存在,外部类就永远不会被垃圾回收。如果您未明确地杀死此活动/片段的CountDownTimer onPause或onDestroy,您将拥有许多外部类和匿名CountDownTimer引用,每次重新加载计时器时都不会对其进行垃圾回收。
不要在匿名类中使用countFrom和waitTime引用(而是创建函数getCountFrom(),getWaitTime()) - 对于mQuiz,btn1等也是如此。不要直接在匿名类之外引用类变量。
了解更多信息 - http://blog.nimbledroid.com/2016/05/23/memory-leaks.html
[Inner Classes]继续,假设我们在Activity的类定义中定义了一个类,称为Inner Class。程序员可能出于多种原因选择这样做,包括提高可读性和封装性。如果我们创建此内部类的实例并维护它的静态引用,该怎么办?此时您可能只是猜测即将发生内存泄漏。
[匿名类]类似地,匿名类也将维护对其内部声明的类的引用。因此,如果在Activity中匿名声明并实例化AsyncTask,则可能会发生泄漏。如果在销毁Activity之后它继续执行后台工作,则对Activity的引用将持续存在,并且在后台任务完成之前不会对其进行垃圾收集。