Вопрос по java, memory-leaks, android – Этот класс Handler должен быть статическим, иначе могут возникнуть утечки: final Handler

5

По приведенному ниже коду 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 ()!

Это почти так же, как этот вопрос:stackoverflow.com/questions/11407943/... ThomasW

Ваш Ответ

3   ответа
5

ка для решения проблемы, как рекомендовано в документации 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);
  }
}
</myclass></myclass>
2

обработчик - Обработчик, идентифицирующий поток, в котором должен происходить обратный вызов. Если ноль, обратный вызов будет происходить из пула потоков процесса.

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

Внутренний класс все еще содержит ссылку на уничтоженную деятельность, он не может быть собран мусором.

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

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

Код дядя код обезьянаЭто полезно, но когда не существует, вызовите нестатический метод в handleMessage (). Когда нужно вызывать нестатический его код не работает. Может я что-то не так делаю? Tapa Save
Дядя кодирует обезьяну?Ответ s (по предоставленной мной ссылке) вам немного помог? Shrikant
Шрикант, я читал эту тему ранее. Пожалуйста, примените в контексте моего кода с вызовом нестатического метода в handleMessage () ... Tapa Save
2

ОтПроверки линтов Android:

HandlerLeak
-----------
Summary: Ensures that Handler classes do not hold on to a reference to an
outer class

Priority: 4 / 10
Severity: Warning
Category: Performance

In Android, Handler classes should be static or leaks might occur. Messages
enqueued on the application thread's MessageQueue also retain their target
Handler. If the Handler is an inner class, its outer class will be retained as
well. To avoid leaking the outer class, declare the Handler as a static nested
class with a WeakReference to its outer class.

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

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

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

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

Похожие вопросы