Этот класс Handler должен быть статическим или может возникнуть утечка: final Handler

В приведенном ниже коде Eclipse генерирует предупреждение «Этот класс обработчика должен быть статическим или может возникнуть утечка».

public class MyActivity extends Activity implements Runnable { final Handler handler = new Handler() { @Override public void handleMessage( Message message) { String sResult = (String) message.obj; if( (sResult != null) && (sResult != "")) { MyNonStatic = (TableLayout) findViewById( R.id.tableLayout); // any non-static method } return; } }; public void run() { final Message message = handler.obtainMessage( 1, MyFunction( context)); handler.sendMessage( message); } public String MyFunction( Context context) { return "MyNewString"; } } 

Я рассматриваю множество тем на сайте, но не получаю решения. Пожалуйста, помогите мне в этом коде?

Добавить: мне нужно вызвать нестатический метод (например, findViewById ()) в handleMessage ()!

Ниже приведен пример использования слабого ссылочного и статического классов обработчика для решения проблемы, как рекомендовано в документации Lint:

 public class MyClass{ //static inner class doesn't hold an implicit reference to the outer class private static class MyHandler extends Handler { //Using a weak reference means you won't prevent garbage collection private final WeakReference<MyClass> myClassWeakReference; public MyHandler(MyClass myClassInstance) { myClassWeakReference = new WeakReference<MyClass>(myClassInstance); } @Override public void handleMessage(Message msg) { MyClass myClass = myClassWeakReference.get(); if (myClass != null) { ...do work here... } } } private final MyHandler mHandler = new MyHandler(this); public void getHandler() { return new MyHandler(this); } } 

Handler – обработчик, определяющий поток, на котором должен произойти обратный вызов. Если значение null, обратный вызов произойдет из пула потоков процесса.

Представьте себе ситуацию. Некоторая активность вызывает PendingIntent.send(...) и помещает non-static inner subclass of Handler . И тогда деятельность уничтожается. Но внутренний класс живет .

Внутренний класс по-прежнему содержит ссылку на разрушенную деятельность, ее нельзя собирать с мусором.

И поэтому вам нужно сделать его статичным.

Источник: обработчики и утечки памяти в Android

Из проверок Android lint :

 HandlerLeak
 -----------
 Резюме. Обеспечивает, чтобы классы обработчика не поддерживали ссылку на
 Внешний класс

 Очередность: 4/10
 Уровень важности: предупреждение
 Категория: Производительность

 В Android классы Handler должны быть статическими или могут возникнуть утечки.  Сообщения
 Помеченные в MessageQueue потока приложений, также сохраняют свою цель
 Handler.  Если обработчик является внутренним классом, его внешний класс будет сохранен как
 Что ж.  Чтобы избежать утечки внешнего класса, объявите обработчика как статичное вложенное
 Класс с WeakReference к его внешнему классу.

Первая часть предупреждения заключается в том, что final Handler handler = new Handler() создает анонимный внутренний класс. Внутренние классы не могут создаваться автономно, вам всегда нужен внешний экземпляр. Помните, как вы могли бы создать это в Java OuterClass.InnerClass innerObject = outerObject.new InnerClass(); , Каждый внутренний объект класса также должен содержать ссылку на внешний объект Outer.this для доступа к внешним членам.

Вторая часть является final Message message = handler.obtainMessage( 1, MyFunction( context)); Имеет дескриптор вашего класса внутреннего обработчика (который имеет обработчик внешнего класса Activity). Если это сообщение живет достаточно долго, мусор не сможет собрать вашу активность.

Что может заблокировать ваше сообщение? К сожалению, инструмент lint не может понять это, поэтому он всегда предупреждает вас о возможной утечке памяти. Если вы уверены в том, что делаете, вы можете подавлять эти сообщения различными способами .

Для вашего случая не будет хорошей идеей сделать Activity Runnable но в любом случае вы можете использовать Handler.post или лучший Activity.runOnUIThread .

Intereting Posts
Как CyanogenMod10 определяет местоположение звонящего? Проблема с добавлением общих элементов arraylist в третьем arraylist, использующем для цикла Двойной фрагмент, вращающийся Android с ActionBar Set Value to Enum – Java Сохранение одной и той же базы данных SQLite при обновлении и Android-приложение от версии Lite до Pro Как проверить существование файла в телефонном справочнике с телефонной связью Изменение высоты относительной компоновки с той же скоростью, что и пользователь. Finger Moves on Layout Как узнать, когда заполняется Android ListView Как загрузить массив строки во фрагмент? Ошибка в создании проекта в Android Studio Динамический ярлык для элемента меню ActionBar? (Android, ActionBarSherlock) Как подключить системные вызовы моего приложения для Android (не привязанное к корневому устройству) Как программно переключаться с помощью кнопок buttonclick в Android Kotlin – Прерывистая ошибка «плохого файла класса» Не удалось установить драйвер USB для Android на Windows 7