2016-12-20 13 views
2

У меня есть коды ниже, которые будут выполнять обратный вызов из другого потока, когда я закончу действие. Итак, как избегать для вызова обратного вызова или кодов в обратном вызове , когда деятельность завершена?Как избежать утечки обратного вызова Runnable?

public static interface Callback{ 
    public void onCallback(); 
} 

class ActivityA { 
    TextView tv = ...; 
    Handler handler = ...; 
    public void onClick(View v) { 
     Business.callThread(new Callback() { 

      @Override 
      public void onCallback() { 
       handler.post(new Runnable(){ 
        public void run(){ 
         tv.setText("xxxx"); 
        } 
       }); 
      } 
     }); 
    } 
} 

class Business { 
    public static void callThread(final Callback listener) { 
     new Thread(new Runnable() { 

      @Override 
      public void run() { 
       try { 
        Thread.sleep(5000); //sleep 5s; 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       listener.onCallback(); 
      } 
     }).start(); 
    } 
} 

ответ

1

Сборщик мусора подсчитывает ссылки на объекты. Однако существует несколько ссылочных типов. Полезно в вашем случае WeakReference:

Слабых ссылки на объекты, которые не препятствуют их референтам из делаются финализируемыми, завершены, а затем утилизированы.

Создание работоспособной как класс с конструктором:

static class CallbackRunnable implements Runnable { 
    WeakReference<Callback> listener; 

    public CallbackRunnable(Callback listener) { 
     this.listener = new WeakReference<Callback>(listener); 
    } 

    @Override 
    public void run() { 
     try { 
      Thread.sleep(5000); //sleep 5s; 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     if (listener.get() == null) { 
      return; 
     } 
     listener.get().onCallback(); 
    } 
} 

затем называют слушателя как:

if (listener.get() == null) { 
    return; 
} 
listener.get().onCallback(); 

callThread реализация метода:

public static void callThread(final Callback listener) { 
    new Thread(new CallbackRunnable(listener)).start(); 
} 
+0

Ну, я действительно не очень понять это, когда 'listener.get() == null' будет b правда? и почему? –

+0

Когда Call объявлен 'new Callback()', он ссылается на 'Activity' (это внутренний объект, объявленный внутри' Activity'). Когда действие должно быть уничтожено, оно помечено сборщиком мусора. Когда сборщик мусора нуждается в памяти, он удаляет ранее отмеченные объекты. Но он автоматически решает, когда нужно ссылаться и что очищать. Это действительно простое и наивное описание, но в основном это работает. –

+0

Я тебя поймаю. Но откуда вы знаете, что «новый обратный звонок» содержит ссылку на эту активность? –

Смежные вопросы