在我第一次从干净状态进入应用程序后处理程序内部,处理程序处理MSG_PULLED操作,但是对main的引用为null。弱引用不为空。怎么可能发生这种情况?
受到这篇文章的启发:This Handler class should be static or leaks might occur: IncomingHandler
static class MainHandler extends Handler {
private final WeakReference<MainActivity> wMain;
static int angle=0;
public MainHandler(MainActivity main) {
super();
this.wMain = new WeakReference<MainActivity>(main);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
MainActivity main = wMain.get();
int what = msg.what;
if(what == MSG_PULLED) {
main.startAnim();
}
}
}
我是如何启动处理程序的:
static MainHandler mainHandler;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainHandler = new MainHandler(this);
mainHandler.sendEmptyMessageDelayed(MSG_PULLED,500);
}
答案 0 :(得分:1)
定期销毁应用中的Activity
个实例,并在旋转显示时创建新的实例。
现在应该发生的情况是旧实例是垃圾收集而只存在新实例。如果你保留旧的,你就会造成泄漏。
由于Handler
在没有更多消息(?)之前不能被垃圾收集,因此它们可以比创建它们的Activity
更长寿,这通常会导致泄漏旧Activity
}(直到可以收集Handler
),因为Handler
通常会强烈引用他们的Activity
。
代码中的WeakReference
方式可以通过保留一个不会阻止垃圾回收的Activity
的弱链接来摆脱这个问题。
问题是你以错误的方式使用get()
方法:get()
只会在原始对象存在时返回它。当它消失时,你得到null
。这里:Activity
将存在,而它仍然是活动的(由系统确定)。
null
也不是一个大问题:当你得到null
Activity
实例不再存在时(可能是新的实例已经创建,也许它已经完全消失了)所以你不能做任何有用的事了。即使您仍然有参考,动画也不会显示。
基本上就像下面这样,你的问题就解决了
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
MainActivity main = wMain.get();
// message arrived after activity death
if (main == null) return;
int what = msg.what;
if(what == MSG_PULLED) {
main.startAnim();
}
}
WeakReference
本身(wMain
)不为null,因为它本身是作为成员变量的强引用。只是其中的内容可以/将在某个时刻null
。