Форум программистов, компьютерный форум CyberForum.ru

Программирование Android

Войти
Регистрация
Восстановить пароль
 
Paket236
2 / 2 / 0
Регистрация: 16.08.2013
Сообщений: 52
#1

Утечка памяти при использовании Handler - Программирование Android

10.10.2014, 14:48. Просмотров 766. Ответов 2
Метки нет (Все метки)

Добрый день, многоуважаемые форумчане .
Прошу помощи в решении проблемы.

Приведу несложный исходный код.

MainActivity.java
Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import android.app.Activity;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.widget.TextView;
 
public class MainActivity extends Activity
{
    TextView textView;
    SoundPool sp;
    int soundID_btn1;
    TimerX timer;
    
    public class TimerX extends CountDownTimer
    {
        public TimerX(long millisInFuture, long countDownInterval)
        {   super(millisInFuture, countDownInterval);
        }
 
        @Override public void onTick(long millisUntilFinished)
        {   textView.setText(Integer.toString((int)millisUntilFinished));
        }
        
        // Вызывается, когда таймер закончил обратный отсчёт
        @Override public void onFinish()
        {   textView.setText("0000");
            method();
        }
    }
    
    @Override protected void onCreate(Bundle savedInstanceState)
    {   super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        textView = (TextView) findViewById(R.id.textView);
        sp = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
        soundID_btn1 = sp.load(this, R.raw.drip4, 1);
    }
    
    @Override protected void onResume()
    {   super.onResume();
        timer = new TimerX(4010, 1000);                 // создаём таймер с начальным временем 4010мсек, который уменьшается каждые 1000мсек на 1000мсек
        timer.start();                                  // запускает таймер
    }
    
    void method()
    {   Handler handler = new Handler();
        handler.postDelayed(new Runnable()
        {   public void run()
            {   sp.play(soundID_btn1, 1, 1, 0, 0, 1);   // воспроизводит звуковой файл, чтобы услышать утечку памяти
                timer.cancel();                         // останавливает старый таймер
                timer = new TimerX(4010, 1000);         // создаёт новый таймер
                timer.start();                          // запускает новый таймер
            }
        }, 5000);
    }
 
    @Override protected void onPause()
    {   super.onPause();
        timer.cancel();                                 // останавливает таймер
    };
}

main.xml
Кликните здесь для просмотра всего текста
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:gravity="center"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    
    <TextView
        android:id="@+id/textView"
        android:text="TextView"
        android:textSize="20pt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
 
</LinearLayout>

Звуковой файл:
Кликните здесь для просмотра всего текста

Скриншот:
Кликните здесь для просмотра всего текста
Утечка памяти при использовании Handler


Приложение простое и работает циклично. При его запуске создаётся и запускается таймер на 4 секунды, каждую секунду он уменьшается на секунду, отображая изменения в TextView. По завершении таймера вызывается метод method(), который после 5-секундной задержки запускает некоторые действия в отдельном потоке, а именно: отменяет старый таймер, создаёт новый и запускает его. Цикл повторяется по новой.

Если нажать на кнопку Back во время обратного отсчёта таймера, то таймер отменится и активити остановится. Вроде бы всё нормально.
НО если нажать на кнопку Back во время 5-секундной задержки (handler.postDelayed(..., 5000); ), то после остановки активити поток продолжит свою работу и бесконечный цикл продолжится. Это можно услышать по звуку. Т.е., как я понимаю, это утечка.

Каким образом нужно изменить код, чтобы от этой утечки избавиться? Я в потоках разбираюсь слабо, поэтому не смог ничего придумать...
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.10.2014, 14:48     Утечка памяти при использовании Handler
Посмотрите здесь:
Утечка памяти при использовании хандлера Android
Утечка памяти Android
Утечка памяти Android
Утечка памяти в Spiner Android
Android FragmentActivity -> DialogFragment (утечка памяти)
Android WebView утечка памяти Android
Android Activity + Service - утечка памяти?
Android Handler при пересоздании активити
Как перенести строку при записи в файл при использовании BufferedWriter? Android
Android Ошибка при использовании фонарика
Android Handler
Android Handler

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Paket236
2 / 2 / 0
Регистрация: 16.08.2013
Сообщений: 52
11.10.2014, 01:47  [ТС]     Утечка памяти при использовании Handler #2
До чего же простым оказалось решение!
В onPause() добавить handler.removeCallbacksAndMessages(null);
dubok79
323 / 121 / 11
Регистрация: 01.11.2012
Сообщений: 586
13.10.2014, 09:14     Утечка памяти при использовании Handler #3
Если следовать вот этой теме, то вы неправильно используете Handler. А handler.removeCallbacksAndMessages(null); я думаю просто костыль. Почитайте, там не сложно переделать в "Правильно".
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru