Android处理程序更改WeakReference

Android处理程序更改WeakReference,android,handler,weak-references,Android,Handler,Weak References,我的静态处理程序对我的活动有一个WeakReference(这是为了防止记录良好的内存泄漏问题) 我发布了一条长时间延迟的消息,我希望将此消息发送到我的活动(应该在前台) 我关心的是,在方向更改时,我的活动被销毁,并且处理程序有一个对应该被销毁的旧活动的引用 为了在我的onCreate活动中绕过这一点,我这样做 if(mHandler == null) mHandler = new LoginHandler(this); else { mHandl

我的静态处理程序对我的
活动
有一个
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);
        }
    }
}
私有静态类LoginHandler扩展处理程序{
私有WeakReference mTarget;
LoginHandler(LoginActivity目标){
mTarget=新的WeakReference(目标);
}
公共无效设置目标(登录活动目标){
mTarget=新的WeakReference(目标);
}
@凌驾
公共无效handleMessage(消息消息消息){
//在此处处理传入消息
LoginActivity活动=mTarget.get();
开关(msg.what){
case.SUCCESS:
活动。doSomething();
打破
违约:
activity.setStatusMessage(“失败”+msg.obj,状态\类型\完成);
}
}
}
我想知道的是,在
onCreate
上更改WeakReference是否有问题,或者这种方法是否还有其他问题


谢谢,

所以我写了下面的测试,以确定我的想法是否正确,而且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);
    }

}
公共类MainActivity扩展活动{
私有静态整数计数=0;
静态登录Handler mHandler;
私有静态类LoginHandler扩展处理程序{
私有WeakReference mTarget;
LoginHandler(主要活动目标){
mTarget=新的WeakReference(目标);
}
公共无效设置目标(主活动目标){
mTarget.clear();
mTarget=新的WeakReference(目标);
}
@凌驾
公共无效handleMessage(消息消息消息){
//int duration=Toast.LENGTH\u LONG;
//在此处处理传入消息
MainActivity=mTarget.get();
activity.update(msg.arg1);
}
}
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(mHandler==null)
mHandler=新登录处理程序(本);
其他的
mHandler.setTarget(本);
((按钮)findviewbyd(R.id.Button)).setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
Message msg=新消息();
msg.arg1=COUNT++;
mHandler.sendMessageDelayed(msg,3000);
}
});
}
@凌驾
公共布尔onCreateOptions菜单(菜单){
//为菜单充气;这会将项目添加到操作栏(如果存在)。
getMenuInflater().充气(R.menu.main,menu);
返回true;
}
私有无效更新(整数计数){
((TextView)findviewbyd(R.id.hello_world)).setText(“hello world@”+count);
}
}

如果您想保留活动对象,可以避开活动的销毁和创建生命周期,解决方案是使用“保留片段”

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

以下链接有更多详细信息:

@Commonware对此有何看法?