Android Handler меняет WeakReference

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

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

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

Чтобы обойти это в моем 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 on onCreate или что-то еще не так с этим подходом?

Благодаря,

Поэтому я написал следующий тест, чтобы выяснить, есть ли у меня правильная идея или нет, и кажется, что подход m правильный. В 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); } } 

Решение о том, чтобы избежать жизненного цикла уничтожения и создания активности, если вы хотите сохранить активные объекты, – это использовать «Хранение фрагментов».

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

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