Android 进度条内存泄漏
Android progress bar memory leak
我有一个进度条从 android CountDownTimer 每 100 毫秒更新一次(使用 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(...) 中泄露了;线。如果我将其注释掉,泄漏就会停止。
更新:
我找不到发生这种情况的任何理由。即使在一个 activity 中,通过循环更新进度条时,似乎也存在内存泄漏。也许这是 Android 本身的错误?我在 Lenovo 设备上使用 Android 5.1。
您遇到的一个问题是您的匿名 CountDownTimer class 引用了它在(变量 countFrom 和 waitTime)中声明的 class。这意味着只要 CountDownTimer 存在,外部 class 就永远不会被垃圾回收。如果你没有明确地杀死这个 Activity/Fragment 的 CountDownTimer onPause 或 onDestroy,你将有许多外部 Class 和匿名 CountDownTimer 引用,它们在你每次重新加载计时器时都不会被垃圾收集。
不要在匿名中使用 countFrom 和 waitTime 引用 class(而是创建函数 getCountFrom()、getWaitTime())- mQuiz、btn1 等也是如此。不要引用 class 直接在你的匿名 class 之外的变量。
了解更多信息 - http://blog.nimbledroid.com/2016/05/23/memory-leaks.html
[Inner Classes] Moving on, let’s say we define a class inside the definition of our Activity’s class, known as an Inner Class. The programmer may choose to do this for a number of reasons including increasing readability and encapsulation. What if we create an instance of this Inner Class and maintain a static reference to it? At this point you might as well just guess that a memory leak is imminent.
[Anonymous Classes] Similarly, Anonymous Classes will also maintain a reference to the class that they were declared inside. Therefore a leak can occur if you declare and instantiate an AsyncTask anonymously inside your Activity. If it continues to perform background work after the Activity has been destroyed, the reference to the Activity will persist and it won’t be garbage collected until after the background task completes.
我有一个进度条从 android CountDownTimer 每 100 毫秒更新一次(使用 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(...) 中泄露了;线。如果我将其注释掉,泄漏就会停止。
更新: 我找不到发生这种情况的任何理由。即使在一个 activity 中,通过循环更新进度条时,似乎也存在内存泄漏。也许这是 Android 本身的错误?我在 Lenovo 设备上使用 Android 5.1。
您遇到的一个问题是您的匿名 CountDownTimer class 引用了它在(变量 countFrom 和 waitTime)中声明的 class。这意味着只要 CountDownTimer 存在,外部 class 就永远不会被垃圾回收。如果你没有明确地杀死这个 Activity/Fragment 的 CountDownTimer onPause 或 onDestroy,你将有许多外部 Class 和匿名 CountDownTimer 引用,它们在你每次重新加载计时器时都不会被垃圾收集。
不要在匿名中使用 countFrom 和 waitTime 引用 class(而是创建函数 getCountFrom()、getWaitTime())- mQuiz、btn1 等也是如此。不要引用 class 直接在你的匿名 class 之外的变量。
了解更多信息 - http://blog.nimbledroid.com/2016/05/23/memory-leaks.html
[Inner Classes] Moving on, let’s say we define a class inside the definition of our Activity’s class, known as an Inner Class. The programmer may choose to do this for a number of reasons including increasing readability and encapsulation. What if we create an instance of this Inner Class and maintain a static reference to it? At this point you might as well just guess that a memory leak is imminent.
[Anonymous Classes] Similarly, Anonymous Classes will also maintain a reference to the class that they were declared inside. Therefore a leak can occur if you declare and instantiate an AsyncTask anonymously inside your Activity. If it continues to perform background work after the Activity has been destroyed, the reference to the Activity will persist and it won’t be garbage collected until after the background task completes.