2

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?

Répondre

3

Cela se produit probablement parce que le ActionBar.TabListener importé provient du package Android plutôt que du package ActionBarSherlock.

Assurez-vous que l'importation est pour com.actionbarsherlock.app.ActionBar.TabListener

Edit: Shockwave a résolu ce seul, mais pour d'autres à venir à travers cette question: Si vous frappez des exceptions ClassNotFound au niveau API inférieur, mais il fonctionne Sur les niveaux d'API supérieurs, vous pouvez suivre certaines étapes pour le déboguer.

  • Assurez-vous que vous n'êtes pas implémentez des interfaces qui ne sont pas disponibles dans votre niveau de l'API minimum (par exemple à l'aide View.OnSystemUiVisibilityChangeListener avant le niveau de l'API 11)

  • Run Android Lint pour vérifier tous les appels à méthodes uniquement disponibles dans les nouveaux niveaux d'API.

+0

J'ai vérifié et il utilise le bon TabListener d'ActionBarSherlock, mais ça ne marche toujours pas. – NSchock

+0

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

+0

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

1

enter image description here essayer d'ajouter le répertoire lib à exporter, cela se produit parce que le temps de compilation de la classe se trouve mais dans l'exécution pas, essayez d'ajouter les bibliothèques à exporter comme dans l'image ci-dessus

la lib dans votre cas est la Projet sherlock

+0

Cela n'a malheureusement pas semblé changer quoi que ce soit. – NSchock