2011-10-02 13 views
5

Desidero eseguire la scansione del classpath per alcune annotazioni in Android.è possibile eseguire la scansione del classpath android per le annotazioni?

ho trovato solo una soluzione a questo problema: http://mindtherobot.com/blog/737/android-hacks-scan-android-classpath/

E come scrive l'autore questa soluzione funziona, ma ha diverse limitazioni. Ci sono dei modi a prova di futuro per fare questo in Android? Qualsiasi libreria che fornisce questa funzionalità?

+0

Mi piacerebbe vedere questa domanda ha risposto. Attualmente sto tentando di risolvere esattamente lo stesso problema. Il framework di scansione delle annotazioni che ho usato in passato è Reflections (http://code.google.com/p/reflections/), ma non riesco a capire come "puntarlo correttamente" al codice compilato- base ... – Andrey

+0

Posso solo pensare di lasciare che Reflections scandisca le annotazioni in fase di compilazione e generi un file XML con quelle informazioni (che supporta, in effetti, supporto), quindi carica tutte le informazioni da quel file in fase di esecuzione (vedere la parte inferiore della pagina del progetto e http://code.google.com/p/reflections/wiki/ReflectionsMojo per i dettagli) – Andrey

risposta

1

Questo funziona per me usando Android 3,0

public static <T extends Annotation> List<Class> getClassesAnnotatedWith(Class<T> theAnnotation){ 

    // In theory, the class loader is not required to be a PathClassLoader 
    PathClassLoader classLoader = (PathClassLoader) Thread.currentThread().getContextClassLoader(); 
    Field field = null; 
    ArrayList<Class> candidates = new ArrayList<Class>(); 

    try { 
     field = PathClassLoader.class.getDeclaredField("mDexs"); 
     field.setAccessible(true); 
    } catch (Exception e) { 
     // nobody promised that this field will always be there 
     Log.e(TAG, "Failed to get mDexs field", e); 
    } 

    DexFile[] dexFile = null; 
    try { 
     dexFile = (DexFile[]) field.get(classLoader); 
    } catch (Exception e) { 
     Log.e(TAG, "Failed to get DexFile", e); 
    } 

    for (DexFile dex : dexFile) { 
     Enumeration<String> entries = dex.entries(); 
     while (entries.hasMoreElements()) { 
     // Each entry is a class name, like "foo.bar.MyClass" 
     String entry = entries.nextElement(); 

     // Load the class 
     Class<?> entryClass = dex.loadClass(entry, classLoader); 
     if (entryClass != null && entryClass.getAnnotation(theAnnotation) != null) { 
      Log.d(TAG, "Found: " + entryClass.getName()); 
      candidates.add(entryClass); 
     } 
     } 
    } 

    return candidates; 
}  

Ho anche creato uno al determin se una classe è stata derivata da X

public static List<Class> getClassesSuperclassedOf(Class theClass){ 

    // In theory, the class loader is not required to be a PathClassLoader 
    PathClassLoader classLoader = (PathClassLoader) Thread.currentThread().getContextClassLoader(); 
    Field field = null; 
    ArrayList<Class> candidates = new ArrayList<Class>(); 

    try { 
     field = PathClassLoader.class.getDeclaredField("mDexs"); 
     field.setAccessible(true); 
    } catch (Exception e) { 
     // nobody promised that this field will always be there 
     Log.e(TAG, "Failed to get mDexs field", e); 
    } 

    DexFile[] dexFile = null; 
    try { 
     dexFile = (DexFile[]) field.get(classLoader); 
    } catch (Exception e) { 
     Log.e(TAG, "Failed to get DexFile", e); 
    } 

    for (DexFile dex : dexFile) { 
     Enumeration<String> entries = dex.entries(); 
     while (entries.hasMoreElements()) { 
     // Each entry is a class name, like "foo.bar.MyClass" 
     String entry = entries.nextElement(); 

     // Load the class 
     Class<?> entryClass = dex.loadClass(entry, classLoader); 
     if (entryClass != null && entryClass.getSuperclass() == theClass) { 
      Log.d(TAG, "Found: " + entryClass.getName()); 
      candidates.add(entryClass); 
     } 
     } 
    } 

    return candidates; 
} 

godere - B

+0

Come avrete notato, questo è fondamentalmente lo stesso codice che ho aggiunto nel collegamento. Lo sto usando e sembra funzionare, ma è molto sperimentale. Comunque, grazie per la risposta (e anche se sembra funzionare bene) non è la soluzione ideale che stavo cercando. –

Problemi correlati