Android Activity:需在onDestroy中手动将View等对象置为null吗?
重点注意:你的Parse异步请求(
getFirstInBackground)才是需要关注的点 比起控件置null,这个异步回调反而更容易出问题!因为这个请求是在后台执行的,等它完成后会回到主线程调用done方法。如果此时你的Activity已经被销毁了,回调里如果还引用着Activity的控件或者成员变量,就会造成内存泄漏(Activity的实例因为被回调持有而无法被GC回收),甚至直接引发空指针崩溃。
给你两个实用的解决办法:
- 在Activity销毁时取消请求:把
ParseQuery对象存为Activity的成员变量,然后在onDestroy里调用它的cancel()方法,这样后台请求就会终止,不会再触发回调。 - 在回调里先判断Activity状态:调用
isDestroyed()或者isFinishing()检查Activity是否还存活,如果已经销毁了,就直接返回,不要执行任何和UI相关的操作。
给你写个示例代码参考:
// 把Query声明为Activity的成员变量 private ParseQuery<ParseUser> getUserQuery; // 发起请求的代码 getUserQuery = new ParseQuery<ParseUser>(ParseUser.class); getUserQuery.whereEqualTo("username", usernameString); getUserQuery.getFirstInBackground(new GetCallback<ParseUser>() { @Override public void done(ParseUser object, ParseException e) { // 先判断Activity是否还活着,避免无效操作 if (isDestroyed() || isFinishing()) { return; } // 正常处理请求结果 if (e == null && object != null) { // 这里再去更新TextView或者RecyclerView的数据 } } }); // 在onDestroy里取消请求 @Override protected void onDestroy() { super.onDestroy(); if (getUserQuery != null) { getUserQuery.cancel(); } }
总的来说:控件和Adapter不用手动置null,但异步请求一定要做好取消或者存活判断,这才是避免内存泄漏和崩溃的关键。
内容的提问来源于stack exchange,提问作者kaya
相关产品推荐
相关产品推荐

