java - 如何修复onDestroy的 'SuperNotCalledException"?

标签 java android exception super

我在 fragment 内使用 onDestroy 来确保退出应用程序时停止处理程序(用于为按钮设置动画),如下面的代码所示:

@Override
public void onDestroy () {
    if (anim1 !=null && run1 !=null) {
        anim1.removeCallbacks(run1);
    }
    super.onDestroy ();
}

anim1 是 Handler; run1 是可运行的。

代码在我的测试设备中按预期工作(运行各种 Android 版本,但不是 6.0 或 8.1 - 正如您将看到的,这将是一个问题)。从 Google Console 报告和一般反馈来看,它也适用于绝大多数用户。

换句话说,如果用户在 Handler/Runnable 仍然存在的情况下尝试离开应用程序(或移动到另一个 fragment ),则不会引发异常,并且 anim1.removeCallbacks(run1); 会按预期触发,不会出现任何错误。

但是,从 Google Console 的报告来看,一些 Android 6.0 和 8.1 用户遇到了 SuperNotCalledException(下面提供的日志)。从数字上看,8.1 用户似乎比 6.0 受到的影响更大

我知道问题出在我的 onDestroy 实现中,因为此错误 (SuperNotCalledException) 仅在我实现上述代码之后才开始出现在 Google 控制台上。在我收到 NPE 之前,因为应用程序退出时处理程序仍在运行(此错误不再存在)。

我只收到了一些关于此问题的错误报告,因此显然它只影响了少数用户。但我想知道我做错了什么以及如何解决它。

我已经研究过其他类似的问题,例如:

Fatal error: supernotcalledexception

NullPointer at OnDestroy

但它们似乎与我的问题无关。 super.onDestroy 在我的代码中,它出现在最后。 logcat 也不太透露(至少对我来说):

Huawei Honor 7A (HWDUA-M), Android 8.1
Report 1 of 1
java.lang.RuntimeException: 
  at android.app.ActivityThread.performDestroyActivity (ActivityThread.java:4679)
  at android.app.ActivityThread.handleDestroyActivity (ActivityThread.java:4697)
  at android.app.ActivityThread.-wrap5 (Unknown Source)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1837)
  at android.os.Handler.dispatchMessage (Handler.java:106)
  at android.os.Looper.loop (Looper.java:166)
  at android.app.ActivityThread.main (ActivityThread.java:6861)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:450)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:936)
Caused by: android.support.v4.app.SuperNotCalledException: 
  at android.support.v4.app.Fragment.performDestroy (Fragment.java:2590)
  at android.support.v4.app.FragmentManagerImpl.moveToState (FragmentManager.java:1566)
  at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState (FragmentManager.java:1759)
  at android.support.v4.app.FragmentManagerImpl.moveToState (FragmentManager.java:1836)
  at android.support.v4.app.FragmentManagerImpl.dispatchStateChange (FragmentManager.java:3244)
  at android.support.v4.app.FragmentManagerImpl.dispatchDestroy (FragmentManager.java:3235)
  at android.support.v4.app.FragmentController.dispatchDestroy (FragmentController.java:265)
  at android.support.v4.app.FragmentActivity.onDestroy (FragmentActivity.java:390)
  at android.support.v7.app.AppCompatActivity.onDestroy (AppCompatActivity.java:209)
  at android.app.Activity.performDestroy (Activity.java:7335)
  at android.app.Instrumentation.callActivityOnDestroy (Instrumentation.java:1249)
  at android.app.ActivityThread.performDestroyActivity (ActivityThread.java:4666)

知道我可以尝试如何进一步解决该问题吗?我感到有点困惑,因为实际上是 3 行代码导致了问题,而且我不知道如何将它们组合在一起。

如果您需要任何进一步的详细信息或代码,请告诉我,我很乐意提供。

最佳答案

我将添加我的解决方案作为答案,以防其他人发现它有用。 事实证明,问题不在于这个特定的 fragment 和代码,而在于另一个类似的 fragment 。

我已经将代码复制/粘贴到了所有这些代码中,但是在某个时候,某个地方,我发现搜索的代码是这样的:

@Override
public void onDestroy () {
    if (anim1 !=null && run1 !=null) {
    anim1.removeCallbacks(run1);
    super.onDestroy ();
    }
}

由于 super.onDestroy () 意外地结束在 if 语句内,因此每当 Activity 被销毁而 anim1 和/或 run1 为空时,它就无法访问。 logcat 不报告发生异常的哪个 fragment ,这一事实并没有使检测变得更容易。

这个故事的寓意是,始终检查代码的所有实例,即使您已经复制/粘贴了它。

关于java - 如何修复onDestroy的 'SuperNotCalledException"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56209776/

相关文章:

java - android studio 3.1 每次rebuild project 看变化

java - 扩展枚举属性

java - AWS Redhat Chromedriver 不适用于 Java selenium

android - 如何从 adb shell 运行 Android 相机应用程序?

c++ - 带有 nothrow 选项的 Operator new 仍然抛出异常

java - JTable 列中的复选框渲染器不正确

android - 在 Android 应用程序中嵌入 Apache SSHD 服务器

Android 模拟器不接受键盘输入 - SDK 工具 rev 20

java - map 或flatMap内的RxJava Single.error

java - 安卓 java.net.SocketTimeoutException : Connection timed out