WeakReference.get() returns 检查后为空

WeakReference.get() returns null after being checked for it

我有一个从视图执行的异步任务,在它的 onPostExecute 中,我使用 weakReference.get() 检索视图的实例,并检查该实例是否不同于 null。 后来在 onPostExecute 中,我从 weakReference.get() 调用了一个方法,我得到了一个 NullPointerException

  1. 从我得到的引用中调用它能解决吗?

  2. weakReference.get() 值与我一开始得到的参考有什么不同吗?

例如,视图的 method() 调用是否可能导致 NullPointerException

Sample :

private WeakReference<View> weakReference;

[...]

@Override
protected void onPostExecute(Boolean result) {    
    View v = weakReference.get();
    if (v == null) {
        return;
    }
    […]
    getView().method();
}

非常感谢。

我不认为在 AsyncTask 期间保存 View 的引用是个好方法。您应该更改以不同方式进行异步工作的体系结构。请查看 Android Jetpack, there you can find best practices approaches for almost every case in Android development. And any problems related to "activity destroyed" state will be handled automatically if you will use Android Architecture Components.

关于您的情况,当垃圾收集器决定时,可以随时清除 WeakReference。所以你随时可以看到"null"是正常的情况。

"Is there any way in which the weakReference.get() value will differ from the reference I got at the start?" - 是的,例如用户将旋转屏幕或 android 系统可以在内存量不足时破坏并重新创建您的 activity。之后 Activity 将重新创建所有视图,这意味着系统将创建所有视图的新实例。

"is it possible that the method() call of the view will lead to a nullPointerException?" - 是的,它实际上经常发生。例如,您启动了 AsyncTask,然后在 AsyncTask 完成之前 - 旋转屏幕。

Q1: 从我得到的参考中调用是否可以解决?

是的,它会通过引用来解决。因此,如果引用为空,则处理它或将其用作 method() 调用。


Q2: weakReference.get() 值与我一开始得到的参考有什么不同吗?

是的,如果发生任何配置更改 (activity/fragment 重新创建自身),意味着重新创建视图并且您的旧视图引用将是 null .


Conclusion: It's good practice to have reference of your view and perform any operation from that reference further