Как исправить «SuperNotCalledException» в onDestroy? - PullRequest
1 голос
/ 19 мая 2019

Я использую onDestroy внутри фрагмента, чтобы убедиться, что обработчик (используемый для анимации кнопки) останавливается при выходе из приложения, как показано в коде ниже:

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

anim1 - Обработчик; run1 - это Runnable.

Код работает так, как задумано в моих тестовых устройствах (под управлением различных версий Android, но не 6.0 или 8.1 - это будет проблемой, как вы увидите). Он также работает для подавляющего большинства пользователей, судя по отчетам консоли Google и общим отзывам.

Другими словами, если пользователь пытается покинуть приложение (или перейти к другому фрагменту), пока обработчик / Runnable все еще там, не генерируется исключение, и anim1.removeCallbacks(run1); запускается, как и ожидалось, без ошибок.

Однако, глядя на отчеты из Google Console, некоторые пользователи Android 6.0 и 8.1 имели SuperNotCalledException (журнал представлен ниже). Численно, пользователи 8.1, кажется, более затронуты по сравнению с 6.0

Я знаю, что проблема в моей реализации onDestroy, потому что эта ошибка (SuperNotCalledException) начала появляться в консоли Google только после Я реализовал приведенный выше код. До того, как я получил NPE из-за того, что обработчик все еще работает, пока приложение закрывается (эта ошибка больше не существует).

Я получаю только несколько сообщений об ошибках, поэтому, видимо, это влияет только на нескольких пользователей. Но мне интересно, что я делаю не так и как это исправить.

Я уже рассматривал другие подобные вопросы, такие как эти:

Неустранимая ошибка: исключение supernotcalledex

NullPointer в 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 строки кода вызывают проблему, и я не могу понять, как еще их собрать.

Если вам нужны какие-либо дополнительные данные или код, дайте мне знать, и я буду рад предоставить их.

1 Ответ

0 голосов
/ 22 мая 2019

Я добавляю свое решение в качестве ответа на случай, если кто-то найдет его полезным.Оказывается, проблема была не в в этом конкретном фрагменте и коде , а в другом подобном фрагменте.

Я скопировал / вставил код во все из них, но в какой-то момент где-то обнаруженный мной код поиска выглядел так:

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

Так как super.onDestroy () случайно закончилсявнутри оператора if он был недоступен, когда действие было уничтожено, в то время как anim1 и / или run1 были нулевыми.Обнаружение этого не было облегчено тем фактом, что logcat не сообщает о , фрагменте которого произошло исключение.

Мораль сказки такова: всегда проверяйте все экземпляры своего кода, даже если вы его скопировали / вставили.

...