NSchock
NSchock

Reputation: 253

Android ActionBarSherlock Tabs, NoClassDefFoundError on Android 2.3 or lower

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: main

   java.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?

Upvotes: 2

Views: 735

Answers (2)

antew
antew

Reputation: 7478

It is probably happening because the ActionBar.TabListener being imported is from the Android package rather than the ActionBarSherlock package.

Make sure that the import is for com.actionbarsherlock.app.ActionBar.TabListener

Edit: 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.

Upvotes: 3

ingyesid
ingyesid

Reputation: 2884

enter image description here try adding the lib to export ,this occurs because the compilation time the class is found but in runtime not, try adding the libraries to export as in the image above

the lib in your case is the sherlock project

Upvotes: 1

Related Questions