如何修复onDestroy的“ SuperNotCalledException”?

时间:2019-05-19 16:25:09

标签: java android exception super

我正在片段中使用onDestroy来确保退出应用程序时停止处理程序(用于对按钮进行动画处理),如以下代码所示:

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

anim1是处理程序; run1是Runnable。

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

换句话说,如果用户在Handler / Runnable仍在的情况下尝试离开应用程序(或移至另一个片段),则不会引发异常,并且anim1.removeCallbacks(run1);会按预期被触发且没有错误

从Google控制台查看报告,但是,一些Android 6.0和8.1用户具有 SuperNotCalledException (下面提供了日志)。从数字上看,与6.0相比,8.1用户似乎受到的影响更大

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

为此,我仅收到一些错误报告,因此显然它仅影响少数用户。但我想知道我在做错什么以及如何解决。

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

Fatal error: supernotcalledexception

NullPointer at OnDestroy

但它们似乎与我的问题无关。 super.onDestroy在我的代码中,它在末尾。日志猫也没有透露(至少对我来说):

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)

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

如果您需要更多详细信息或代码,请告诉我,我们很乐意提供。

1 个答案:

答案 0 :(得分:0)

我正在添加解决方案作为答案,以防其他人发现它有用。 原来,问题不是在这个特定的片段和代码中,而是在另一个类似的片段中。

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

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

由于super.onDestroy ()意外地结束在if语句内,因此在anim1和/或run1为空的情况下销毁活动时,它是不可达的。由于logcat不会报告发生异常的哪个片段,因此检测它并不容易。

故事的寓意是,即使已复制/粘贴了代码,也请始终检查代码的所有实例。