J'essaie de faire en sorte que mon application Android supporte ActionBar sur les versions inférieures d'Android, donc j'utilise ActionBarSherlock 4.2.0. J'utilise aussi le "NotificationCompat2-1.1.2" du même développeur pour une meilleure prise en charge des notifications. Par conséquent, l'application dispose d'onglets ActionBar, pour lesquels j'utilise ActionBar.TabListener. Ma mise en œuvre de ceci ressemble à ceci:Android ActionBarSherlock Tabs, NoClassDefFoundError sur Android 2.3 ou inférieur
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
}
}
Mes fragments étendent la classe SherlockFragment.
Donc, tout cela fonctionne très bien sauf lorsque je tente de l'exécuter sur un appareil qui ne supporte pas nativement l'ActionBar, c'est à dire une version Android inférieure à 3.0. Donc, il semblerait que ActionBarSherlock ne fonctionne pas correctement pour ce qu'il est réellement destiné à faire.
L'erreur que je reçois est:
ERREUR/dalvikvm (330): Impossible de trouver la classe 'com.shockwave.clockproj.StopwatchFragment', référencé à partir de la méthode com.shockwave.clockproj.ClockMain.onCreate 11-16 16: 23: 50,165: eRREUR/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)
la ligne où l'erreur apparaît est où instancier l'onglet, comme ceci:
ActionBar.Tab stopwatchTab = actionBar.newTab().setText("Stopwatch").setTabListener(new TabListener<StopwatchFragment>(this, "Stopwatch", StopwatchFragment.class));
Donc, apparemment, il ne peut pas trouver la définition de classe pour les fragments, mais seulement sur Android 2.3 ou moins. Comment puis-je réparer ça?
J'ai vérifié et il utilise le bon TabListener d'ActionBarSherlock, mais ça ne marche toujours pas. – NSchock
Hmm, pouvez-vous poster le code pour StopwatchFragment? Quand j'ai rencontré des erreurs ClassNotFound comme ça, c'était parce que mon Fragment/Activity implémentait une interface non disponible sur ce niveau d'API. Dans mon cas c'était avec un OnSystemUiVisibilityChangeListener. – antew
Pas besoin, vous m'avez indiqué dans la bonne direction en disant cela. J'utilisais NumberPickers, qui ne sont apparemment pas disponibles en 2.3. Je viens de changer l'implémentation en une bibliothèque personnalisée et tout a fonctionné correctement. Maintenant, les NumberPickers sont foutus, mais au moins j'ai résolu ce problème. Je vais marquer cela comme la réponse parce que vous m'avez indiqué dans la bonne direction dans les commentaires (est-ce la bonne pratique ici?). – NSchock