Anotación personalizada de Java y carga dinámica

Estoy tratando de desarrollar ORM para la sincronización de la base de datos y decidió dar reflexión Java ir. Tengo una biblioteca que define Anotaciones sincronizadas como esta

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

En el proyecto android uso esta anotación para marcar una clase de 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 alguna investigación, finalmente se escribió un método "loader" que permite descubrir clases de modelo en el apk actual. Debe recuperar todas las clases que están marcadas como "Sincronizado", 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 funcionan. Al depurar noté que la anotación procedente 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é no de mis intentos anteriores tuvo éxito. Cuando se intenta lanzar directamente – se produce una excepción de conversión (comprensiblemente). Básicamente estoy en una pérdida aquí así que cualquier idea es bienvenida.

Modelo de método de carga (en proyecto de 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 la clase necesita ser encadenado de la siguiente manera:

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

Si todavía no tienes idea de lo que estoy hablando, gracias por leer este largo post (-.

Obtén la anotación que te interesa:

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

Actualizar:

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

  • Java Reflection - Obtener todos los nombres de variables de instancia de una clase
  • Clase personalizada que carga / reemplaza las clases nativas de Android
  • Soporte de la clase Robolectric de Android. Cómo tener las referencias de la clase de biblioteca R desde el proyecto de aplicación
  • Proguard y reflexión en Android
  • Cargador de clases personalizado para android?
  • Interceptar llamadas de método
  • ¿Es posible cargar dinámicamente una biblioteca en tiempo de ejecución desde una aplicación de Android?
  • ¿Se considera reflexión y en qué grado?
  • Reflexión Java: implementa la interfaz y pasa a otra clase
  • Android, ¿cómo borrar la lista de tareas recientes que podría obtener desde el botón Inicio en la mayoría de teléfono? ¿La reflexión es una manera posible?
  • Compruebe si el objeto tiene un método en Java?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.