2011-02-24 28 views
6

Estoy tratando de desarrollar ORM para la sincronización de la base de datos y decidí dar un vistazo a la reflexión de Java. Tengo una biblioteca que define anotación Sincronizada como estoAnotación personalizada de Java y carga dinámica

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.TYPE) 
@Inherited 
public @interface Synchronised { 
    String tableName(); 
    SynchronisationType synchronisationType(); 
} 

En proyecto androide utilizo esta anotación para marcar una clase del modelo

@Synchronised(tableName="UserAccounts", synchronisationType=SynchronisationType.DownloadOnly) 
public class UserAccount { 
    @SynchronisedField(fieldName="CompanyFk") 
    private int companyId; 
    @SynchronisedField(fieldName="Id") 
    private int userId; 
    @SynchronisedField(fieldName="Username") 
    private String username; 
    @SynchronisedField(fieldName="Password") 
    private String password; 
    @SynchronisedField(fieldName="Salt") 
    private String salt; 
    @SynchronisedField(fieldName="IsLocked") 
    private boolean isLocked; 
    @SynchronisedField(fieldName="HasMobileAccess") 
    private boolean hasMobileAccess; 
} 

Después de algunas investigaciones un método "cargador" fue finalmente escrito que permite descubrir clases modelo en apk actual. Debería recuperar todas las clases marcadas como "Sincronizadas", pero el problema aquí es que getAttribute (Synchronised.class) no funciona. La iteración manual de anotaciones y la búsqueda del atributo (instanceof, etc.) tampoco funciona. Al depurar noté que la anotación proveniente de la reflexión es en realidad un proxy (getClass() da "class Proxy2", mientras que annotation.AnnotationType() devuelve el nombre correcto) - esto explica por qué ninguno de mis intentos previos tuvo éxito. Al intentar lanzar directamente, se lanza una excepción de lanzamiento (comprensiblemente). Básicamente estoy perdido aquí, así que cualquier idea es bienvenida.

Método de los modelos de carga (en el proyecto de la biblioteca):

public static List<Class> getModels(Context context, String packageName) 
     throws IOException, URISyntaxException, ClassNotFoundException, 
      NameNotFoundException { 

     String apkName = context.getPackageManager().getApplicationInfo(packageName, 0).sourceDir; 
     DexFile dexFile = new DexFile(apkName); 
     //PathClassLoader classLoader = new PathClassLoader(apkName, ClassLoader.getSystemClassLoader());  
     PathClassLoader classLoader = new PathClassLoader(apkName, Thread.currentThread().getContextClassLoader()); 

     List<Class> classes = new ArrayList<Class>(); 
     Enumeration<String> entries = dexFile.entries(); 

     while (entries.hasMoreElements()) { 

      String entry = entries.nextElement(); 
      // only check items that exist in source package and not in libraries, etc. 
      if (entry.startsWith(packageName)) { 
       Log.d(TAG, "Entry: " + entry); 

       Class<?> entryClass = classLoader.loadClass(entry);//dexFile.loadClass(entry, classLoader); 
       if (entryClass != null) { 
        Annotation[] annotations = entryClass.getAnnotations(); 
        for (Annotation annotation : annotations) { 
         if (annotation instanceof Synchronised) { 
          classes.add(entryClass); 
         } 
        } 
       } 
      }    
     } 

     return classes;  
    } 

[Solución] El cargador de clases tiene que estar encadenado como esto:

PathClassLoader classLoader2 = new PathClassLoader(apkName, Thread.currentThread().getContextClassLoader()); 
DexClassLoader classLoader = new DexClassLoader(apkName, new ContextWrapper(context).getCacheDir().getAbsolutePath(), null, classLoader2); 

Si todavía tiene ni idea de lo que estoy hablando, gracias por leer esta publicación larga (-

Respuesta

2

Obtenga una anotación que le interese:

Annotation<Synchronised> annotation = entryClass.getAnnotation(Synchronised.class); 

Actualización:

El problema es que DexFile.getClass() devuelve un parecer proxy. OP ha encontrado el anser y ha actualizado la pregunta con una solución.

Cuestiones relacionadas