Próbuję opracować ORM do synchronizacji bazy danych i postanowiłem dać refleksji Java. Mam biblioteki, który definiuje Synchronized adnotacji jak tenAdnotacja Java i dynamiczne ładowanie
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
public @interface Synchronised {
String tableName();
SynchronisationType synchronisationType();
}
w Android projektu Używam tego adnotacji oznaczyć klasę modelu
@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;
}
Po jakimś dochodzeniu „ładowarka” metoda została ostatecznie napisane, że pozwala na odkrywanie Klasy modelowe w bieżącym apk. Powinien pobrać wszystkie klasy oznaczone jako "zsynchronizowane", ale problem polega na tym, że getAttribute (Synchronised.class) nie działa. Ręczne iterowanie adnotacji i wyszukiwanie atrybutu (instanceof, itp.) Również nie działa. Podczas debugowania zauważyłem, że adnotacja pochodząca z odbicia jest w rzeczywistości proxy (getClass() daje "klasę Proxy2", podczas gdy adnotacja.AnnotationType() zwraca poprawną nazwę) - to tłumaczy, dlaczego nie udało mi się osiągnąć poprzednich prób. Podczas próby rzutowania bezpośrednio - wyrzucany jest wyjątek (zrozumiałe). Zasadniczo brakuje mi tutaj, więc każdy pomysł jest mile widziany.
metoda model załadunku (w projekcie biblioteki):
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;
}
[ROZWIĄZANIE] Ładowarka klasa musi być przykuty tak:
PathClassLoader classLoader2 = new PathClassLoader(apkName, Thread.currentThread().getContextClassLoader());
DexClassLoader classLoader = new DexClassLoader(apkName, new ContextWrapper(context).getCacheDir().getAbsolutePath(), null, classLoader2);
Jeśli nadal nie masz pojęcia, co mam . mówisz, dzięki za przeczytanie tego długiego posta (-
Gdzie znalazłeś ogólną wersję getAnnotations? Widzę tylko getAnotation (klasa) i getAnnotations(). – Audrius
Oh my bad: nie zwraca tablicy. Ale jak to możliwe - jedna klasa może mieć tylko jedną adnotację typu Synchronizowanego na tym: http://developer.android.com/reference/java/lang/Class.html#getAnnotation(java.lang.Class ) –
To prawda , ale to jest kwestia, którą mam. getAnnotation (Synchronised.class) po prostu zwraca wartość null. Jeśli używam getAnnotations() i iteruję przez nią, widzę adnotację, ale wygląda jak dynamiczny serwer proxy, więc nawet porównywanie klas nie działa. adnotation.getClass(). toString() daje mi "class Proxy2", annotation.annotationType(). toString() daje mi poprawną nazwę klasy. Zakładam więc, że możliwe jest pobranie mojego prawdziwego obiektu adnotacji z dynamicznego proxy, ale nie jestem pewien jak. – Audrius