2013-08-14 4 views
6

Мой статический обработчик имеет WeakReference для моего Activity (это предотвращает проблему документированной утечки памяти).Android Handler change WeakReference

Я отправляю сообщение с длинной задержкой и хочу, чтобы это сообщение дошло до моей активности (что должно быть на переднем плане).

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

Чтобы обойти это в моем onCreate для осуществления этой деятельности, я делаю это.

if(mHandler == null) 
     mHandler = new LoginHandler(this); 
    else { 
     mHandler.setTarget(this); 
    } 

И мой обработчик объявлен как статический глобальные переменный:

private static LoginHandler  mHandler   = null; 

и реализующий класс также статичный, как показано ниже:

private static class LoginHandler extends Handler { 

    private WeakReference<LoginActivity> mTarget; 

    LoginHandler(LoginActivity target) { 
     mTarget = new WeakReference<LoginActivity>(target); 
    } 

    public void setTarget(LoginActivity target) { 
     mTarget = new WeakReference<LoginActivity>(target); 
    } 

    @Override 
    public void handleMessage(Message msg) { 
     // process incoming messages here 
     LoginActivity activity = mTarget.get(); 
     switch (msg.what) { 
      case Constants.SUCCESS: 
       activity.doSomething(); 
       break; 

      default: 
       activity.setStatusMessage("failed " + msg.obj, STATUS_TYPE_DONE); 
     } 
    } 
} 

То, что я хочу знать, если есть что-то не так с изменением WeakReference на onCreate или что-то еще не так с этим подходом?

Спасибо,

+0

@CommonsWare какое-либо мнение по этому поводу? – Ali

ответ

5

Так что я написал следующий тест, чтобы выяснить, имел ли я право идеи или нет, и кажется, что т подход является правильным. В onCreate мы меняем WeakReference, и отправленное сообщение всегда будет доставлено в действие, которое находится на переднем плане. Если вы измените этот код, чтобы всегда создавать новый обработчик в onCreate, вы заметите, что сообщения об обновлении не доставляются.

public class MainActivity extends Activity { 

    private static int COUNT = 0; 

    static LoginHandler mHandler; 

    private static class LoginHandler extends Handler { 

     private WeakReference<MainActivity> mTarget; 

     LoginHandler(MainActivity target) { 
      mTarget = new WeakReference<MainActivity>(target); 
     } 

     public void setTarget(MainActivity target) { 
      mTarget.clear(); 
      mTarget = new WeakReference<MainActivity>(target); 
     } 

     @Override 
     public void handleMessage(Message msg) { 
      // int duration = Toast.LENGTH_LONG; 
      // process incoming messages here 
      MainActivity activity = mTarget.get(); 
      activity.update(msg.arg1); 
     } 
    } 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     if(mHandler == null) 
      mHandler = new LoginHandler(this); 
     else 
      mHandler.setTarget(this); 

     ((Button)findViewById(R.id.button)).setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       Message msg = new Message(); 
       msg.arg1 = COUNT++; 
       mHandler.sendMessageDelayed(msg, 3000); 

      } 
     }); 

    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.main, menu); 
     return true; 
    } 

    private void update(int count) { 
     ((TextView) findViewById(R.id.hello_world)).setText("Hello World @ "+ count); 
    } 

} 
0

Раствор в деться с деятельностью уничтожим-и создать жизненный цикл, если вы хотите сохранить активные объекты, чтобы сделать использование «Retent Фрагменты».

Идея проста: вы сообщаете системе Android «сохранить» свой фрагмент, когда связанная с ним деятельность уничтожается и создается повторно. И убедитесь, что вы захватили контекст текущей активности в вызываемом фрагменте onAttach(), поэтому вы всегда обновляете правильную активность.

Ниже ссылка имеет более подробную информацию: http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html