Android Handler 改变 WeakReference

7
我的静态处理程序对我的活动有一个弱引用(这是为了防止出现已知的内存泄漏问题)。
我发布了一条延迟很长的消息,希望这条消息被传递到我的活动中(该活动应该在前台)。
我的担忧是,在方向变化时,我的活动会被销毁,而处理程序则对旧活动保留着引用,但应该已经被销毁了。
为了解决这个问题,在活动的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);
        }
    }
}

我想知道在onCreate中更改WeakReference是否存在问题,或者这种方法还有其他问题吗?
谢谢。

@CommonsWare 你对此有什么看法吗? - Ali
2个回答

6

因此,我编写了以下测试以确定我的想法是否正确,并且似乎我的方法是正确的。在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

如果你想保留活动对象,解决活动的销毁和创建周期问题的一个方法是利用“保留片段”。

这个想法很简单,你告诉Android系统在关联的活动被销毁和重新创建时“保留”你的片段。并确保在片段的onAttach()可调用中获取当前活动的上下文,以便始终更新正确的活动。

以下链接有更多详细信息: http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接