我的静态处理程序对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);
}
}
}
我想知道的是,更改onCreate
上的WeakReference是否有问题,或者这种方法还有什么问题吗?
谢谢,
答案 0 :(得分:5)
所以我编写了以下测试,以确定我是否有正确的想法,似乎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);
}
}
答案 1 :(得分:0)
如果你想保留活动对象,那么逃避活动破坏和创建生命周期的解决方案就是利用“Retent Fragments”。
这个想法很简单,你告诉Android系统“保留”你的片段,当它的相关活动被破坏并重新创建时。并确保在片段的onAttach()可调用中获取当前活动的上下文,因此您始终更新正确的活动。
以下链接有更多详情: http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html