Fragging Fragments

Posted by on Apr 30, 2012 in work

Android has been enthusiastically pushing fragments ever since they were added in Honeycomb. They were primarily created to improve code re-use across handset and tablet UIs; in the most common case, tablets will load fragments into two panes on one screen, while handsets will load one fragment per screen. However, fragments also get used in other cases. They’re the preferred replacement for the old Tab, and play a key role in the very useful ViewPager support class.

This is great when it works, but makes it all the more annoying when they fail to behave. We recently ran into a problem while building a UI that involved several tabs. When launching a new Activity from a tab other than the first one, the app would crash with a NullPointerException deep within the FragmentManager call stack.

As usual, the open-source nature of Android makes these sorts of bugs easier to track down (have I mentioned how glad I am to finally have source again after going on a fast during the Honeycomb era?). It turns out that it’s  a problem with FragmentManager, which fails to create an internal Bundle under certain circumstances (specifically, if the internal “user visible hint” flag hasn’t been raised). A few enterprising souls have recently identified the bug, and Google should be patching it shortly.

Of course, there’s still a question of how to solve the problem. For now, we’re taking the approach of avoiding the bug by overriding onSaveInstanceState in our Activity and not calling through to the superclass. That works fine for our app, but if yours relies on this method to save its UI state, then you’ll need to selectively replicate that functionality, which would be tedious and risky. Once the bug is fixed, you can grab the updated build of the support package; however, this requires you to convert all of your Fragment-related code to use the android.support.v4 versions instead of the android.app versions, which in turn may cause other issues – for example, the android.support.v13 version of FragmentPagerAdapter uses regular Fragments and not the v4 support versions. Eventually the fix should show up in the standard platform version of FragmentManager, but not every device will necessarily get that fix.

The morals of the story: More recent additions to an API should be viewed with caution. Take advantage of the Android source code – if you haven’t already linked to it in Eclipse, I highly recommend it, as it will even make your own bugs easier to find. And do report real issues you find to Google so they can fix them.