Monday, September 2, 2013

Android Framework Bug with TimePicker Coupled with Dialog

The other day i found a bug that seemed unsolvable, relating to the fact that it was deep inside the android framework and the android operating system. That fact that using a timepicker inside a dialog and managing its lifecycle with "showDialog" cause the application to crash on an orientation change. This crash does not occur on any emulator.

Being aware of the fact that this problem was within the android framework and not in my code, i decided to dig around through the android framework source code, setting break points and trying to figure out what was going wrong, finally after a few days of digging, i figured out that the dialog and time picker both are trying to restore the time pickers state but the dialog(parent) actually assigns a blank value to the timepicker hence causing the exception seen. The exception is as follows:

FATAL EXCEPTION: main
java.lang.IndexOutOfBoundsException: setSpan (2 ... 2) ends beyond length 0
     at android.text.SpannableStringBuilder.checkRange(SpannableStringBuilder.java:978)
     at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:549)
     at android.text.SpannableStringBuilder.setSpan(SpannableStringBuilder.java:541)
     at android.text.Selection.setSelection(Selection.java:74)
     at android.widget.EditText.setSelection(EditText.java:97)
     at android.widget.NumberPicker$SetSelectionCommand.run(NumberPicker.java:1632)
     at android.os.Handler.handleCallback(Handler.java:587)
     at android.os.Handler.dispatchMessage(Handler.java:92)
     at android.os.Looper.loop(Looper.java:132)
     at android.app.ActivityThread.main(ActivityThread.java:4028)
     at java.lang.reflect.Method.invokeNative(Native Method)
     at java.lang.reflect.Method.invoke(Method.java:491)
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
     at dalvik.system.NativeStart.main(Native Method)

The solution was quite simple at the end when i understood what was causing the problem (it took quite some time to understand) just tell the timepickers parent not to manage the saved state, hence the following to lines were added under the fetching of the control.

//Line I mentioned
tp = (TimePicker) findViewById(R.id.timePickerComponent);
//two lines to add after
tp.setSaveFromParentEnabled(false);
tp.setSaveEnabled(true);
LESSON LEARNED : Its not impossible to move mountains.

Well comments and views are welcome, till next time! 

2 comments:

  1. i have been getting same type of issue ....when i am setting maxlength of edittext and inserting values on click of buttons (like 0 to 9 dialpad something). Could you please tell if this also same issue ?

    ReplyDelete
    Replies
    1. Could you Tell me the Version details of android your using and paste the stack trace?

      Delete