Android-обработчик изменяет 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 на onCreate или что-то еще не так с этим подходом?

Спасибо,

2 ответа

Решение

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

Другие вопросы по тегам