mrpear.net logo one IT guy's personal web site
ČESKY | ► ENGLISH |
twitter icon twitter icon google plus icon flickr icon 500px icon linkedin icon

Android 2.x NoClassDefFoundError caused by Fragment or FragmentManager

In my recent update of bizCard Manager I've implemented Android Navigation Drawer and beacause I wanted to keep my app running even on APIs lower then Drawer's requiered API level 11 I've used support library that runs on devices with API 7. But shortly after publishing the update I've received numerous crash reports with NoClassDefFoundError caused by FragmentManager, but only from devices running on API lower then 11 (Android 2.x). For anybody who is facing the same problem here is what was the probolem in my case.
The most confusing part for me about the problems with Navigation Drawer was that the app worked smoothly on all devices that were in my reach; but all of them was on Android 4.0 or higher. Only after I debugged the code on real Android 2.x device I was able to look what's wrong inside the code (well for some reason I do not debug my apps on emulators but on real devices).

What about ProGuard

The net is full of solutions based on playing with ProGuard configuration files because it might look like the requiered class has been removed by Proguard optimalization. I've been trying to tweak my ProGuard config file to keep all the requiered stuff in my package but it didn't lead to any success nor change.

Debugging the real problem

When I attached the debugging Android device (Samsung Galaxy Mini) with Android 2.5 it turned out clearly that the app crashes when it is creating instance of FragmentManager class. Now what helped me out was hovering over the FragmentManager class in the Eclipse to see that this class is imported from android.app package
android.app.FragmentManager
and it is obvious this package requieres API level 11. But the Android 2.x is below that level and since then there was no doubt that this was the real case why it's been crashing on startup.
Fixing the problem was easy, removing two imports
android.app.Fragment
android.app.FragmentManager
and adding two new ipomrts from support library
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
fixed the problem along with calling
FragmentManager fragmentManager = getSupportFragmentManager();
instead of API level 11 code
FragmentManager fragmentManager = getFragmentManager();
Now the biggest question for me is why Eclipse allowed me to use API level 11 code even though I'm targetting my app to minimum API level 7.

invalidateOptionsMenu() and API < 11

FragmentManager was not only the one thing that requiered fixing the Navigation Drawer functionality. Another crashes were caused by calling the method
invalidateOptionsMenu()
This method is available only in API starting from level 11 and if you want to use it on lower levels, you have two choices how to replace your code:
ActivityCompat.invalidateOptionsMenu(Activity activity)
for example if calling from MainActivity call
ActivityCompat.invalidateOptionsMenu(MainActivity.this)
Or just call
supportInvalidateOptionsMenu()
That was it. Let me know your feedback in comments down below. Thank you!
Ads

Comments

24. 5. 2014 9:11:33, Shuvro Pal
Very good solutions that work for me. Appreciate your sharing.

What do you think?

:
:
(not requiered and non public, used for further contact)
: