【问题标题】:WeakReference.get() returns null after being checked for itWeakReference.get() 在检查后返回 null
【发布时间】:2019-03-01 02:03:24
【问题描述】:

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

  1. 是否可以通过从我获得的参考中调用它来解决?

  2. weakReference.get() 的值是否与我一开始得到的参考值不同?

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

示例:

private WeakReference<View> weakReference;

[...]

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

非常感谢。

【问题讨论】:

    标签: android android-asynctask nullpointerexception weak-references


    【解决方案1】:

    我认为在 AsyncTask 期间保存 View 的引用不是一个好方法。您应该以不同的方式更改执行异步工作的架构。请查看Android Jetpack,在那里您可以找到适用于 Android 开发中几乎所有案例的最佳实践方法。如果您使用Android Architecture Components,任何与“活动已销毁”状态相关的问题都会自动处理。

    关于您的情况,WeakReference 可以在垃圾收集器决定时随时清除。所以任何时候都能看到“null”是正常的。

    “weakReference.get() 值与我一开始得到的参考值有什么不同吗?” - 是的,例如用户将旋转屏幕或 android 系统可以在内存量低时破坏并重新创建您的活动。之后将重新创建具有所有视图的 Activity,这意味着系统将创建所有视图的新实例。

    “视图的method()调用是否会导致nullPointerException?” - 是的,它实际上经常发生。例如,您启动了 AsyncTask,然后在 AsyncTask 完成之前 - 旋转您的屏幕。

    【讨论】:

    • 非常感谢维托。我必须说这个遗留代码不是我的。我们希望将 Jetpack 引入我们的代码。
    【解决方案2】:

    Q1: 通过我得到的参考调用它会解决吗?

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


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

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


    结论:参考您的视图并进一步从该参考执行任何操作是一种很好的做法

    【讨论】:

      猜你喜欢
      • 2022-11-30
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 2012-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多