2014-04-26

Tipp: Was es mit NPEs in updateInputState() auf sich hat

Ich wurde von einer Firma angeschrieben, die im Auftrag eines Geräteherstellers Fehlern in Android-Apps nachgeht. Die Fehlerbeschreibung schien zunächst unspezifisch; nachstellen konnte ich das Problem nicht. Allerdings liefert die Developer Console ja zum Glück tiefere Einblicke in die Abstürze:

 

java.lang.RuntimeException: Unable to pause activity {com.thomaskuenneth.android.birthday/com.thomaskuenneth.android.birthday.TKBirthdayReminder}: java.lang.NullPointerException
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3204)
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3159)
at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3137)
at android.app.ActivityThread.access$900(ActivityThread.java:165)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1337)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5450)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at android.widget.TimePicker.updateInputState(TimePicker.java:846)
at android.widget.TimePicker.onSaveInstanceState(TimePicker.java:561)
at android.view.View.dispatchSaveInstanceState(View.java:13117)
at android.view.ViewGroup.dispatchSaveInstanceState(ViewGroup.java:2822)
at android.view.ViewGroup.dispatchSaveInstanceState(ViewGroup.java:2828)
at android.view.ViewGroup.dispatchSaveInstanceState(ViewGroup.java:2828)
at android.view.ViewGroup.dispatchSaveInstanceState(ViewGroup.java:2828)
at android.view.ViewGroup.dispatchSaveInstanceState(ViewGroup.java:2828)
at android.view.View.saveHierarchyState(View.java:13100)
at com.android.internal.policy.impl.PhoneWindow.saveHierarchyState(PhoneWindow.java:1930)
at android.app.Dialog.onSaveInstanceState(Dialog.java:405)
at android.app.TimePickerDialog.onSaveInstanceState(TimePickerDialog.java:216)
at android.app.Activity.saveManagedDialogs(Activity.java:1269)
at android.app.Activity.performSaveInstanceState(Activity.java:1187)
at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1240)
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3185)
... 12 more

Warum sollte eine interne Methode meine App abstürzen lassen? Erstaunlicherweise liefert die Suche nach updateInputState hilfreiche Treffer, unter anderem diesen. Dort steht:

When running on an ICS device, but using against an old build target the TimePicker shows the older AM/PM button instead of the newer spinner. This is dealt with in code for backwards compatibility - TimePicker.java attaches listeners either to mAmPmButton or mAmPmSpinnerInput accordingly. There are checks in most applicable to handle the appropriate case. The function updateInputState() however has no check and is blindly assuming mAmPmSpinnerInput isn't null. This will cause a force close on apps using it that have an active InputMethodManager at the time (line 553 in TimePicker.java).

TKBirthdayReminder ist in der noch aktuellen Version 2.0.6 tatsächlich auf API Level 7 eingestellt, läuft also im Kompatibilitätsmodus. Ich werde den jetzt mal auf 17 setzen und sehen, was passiert. Haben Sie ähnliche Phänomene beobachtet? Schreiben Sie mir…

No comments:

Post a Comment