I’m trying to make my Android app have ActionBar support on lower versions of Android so I’m using ActionBarSherlock 4.2.0. I’m also using the same developer’s “NotificationCompat2-1.1.2” for better notification support.
So the app has ActionBar tabs, which I’m using the ActionBar.TabListener for. My implementation of this looks like this:
public static class TabListener<T extends SherlockFragment> implements ActionBar.TabListener {
private final SherlockFragmentActivity mActivity;
private final String mTag;
private final Class<T> mClass;
private final Bundle mArgs;
private android.support.v4.app.Fragment mFragment;
public TabListener(SherlockFragmentActivity activity, String tag, Class<T> clz) {
this(activity, tag, clz, null);
}
public TabListener(SherlockFragmentActivity activity, String tag, Class<T> clz, Bundle args) {
mActivity = activity;
mTag = tag;
mClass = clz;
mArgs = args;
// Check to see if we already have a fragment for this tab, probably
// from a previously saved state. If so, deactivate it, because our
// initial state is that a tab isn't shown.
mFragment = mActivity.getSupportFragmentManager().findFragmentByTag(mTag);
if (mFragment != null && !mFragment.isDetached()) {
FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction();
ft.detach(mFragment);
ft.commit();
}
}
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
if (mFragment == null) {
mFragment = Fragment.instantiate(mActivity, mClass.getName(), mArgs);
ft.add(android.R.id.content, mFragment, mTag);
} else {
ft.attach(mFragment);
}
}
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
if (mFragment != null) {
ft.detach(mFragment);
}
}
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
//Do nothing
}
}
My fragments extend the SherlockFragment class.
So this all works fine except when I try to run it on a device that doesn’t natively support the ActionBar, ie an Android version less than 3.0. So it would appear that ActionBarSherlock isn’t working properly for what it’s actually intended to do.
The error I get is:
ERROR/dalvikvm(330): Could not find class ‘com.shockwave.clockproj.StopwatchFragment’, referenced from method com.shockwave.clockproj.ClockMain.onCreate
11-16 16:23:50.165: ERROR/AndroidRuntime(330): FATAL EXCEPTION: mainjava.lang.NoClassDefFoundError: com.shockwave.clockproj.StopwatchFragment at com.shockwave.clockproj.ClockMain.onCreate(ClockMain.java:20) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663) at android.app.ActivityThread.access$1500(ActivityThread.java:117) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:123) at android.app.ActivityThread.main(ActivityThread.java:3683) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:507) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) at dalvik.system.NativeStart.main(Native Method)
The line where the error appears is where instantiate the tab, like so:
ActionBar.Tab stopwatchTab = actionBar.newTab().setText("Stopwatch").setTabListener(new TabListener<StopwatchFragment>(this, "Stopwatch", StopwatchFragment.class));
So apparently it can’t find the class definition for the fragments, but only on Android 2.3 or less. How do I fix this?
It is probably happening because the
ActionBar.TabListenerbeing imported is from the Android package rather than the ActionBarSherlock package.Make sure that the import is for
com.actionbarsherlock.app.ActionBar.TabListenerEdit: Shockwave solved this on his own, but for others coming across this issue: If you are hitting ClassNotFound exceptions on a lower API level, but it works on higher API levels there are some steps you can take to debug it.
Make sure that you aren’t implementing any interfaces that aren’t available in your minimum API level (e.g. using View.OnSystemUiVisibilityChangeListener before API level 11)
Run Android Lint to check for any calls to methods only available in newer API levels.