2010-01-07 4 views
6

Ich habe eine Android-Anwendung (Java), die fein gearbeitet, wenn sie mit dem Android 1.6 SDK mit dem folgenden Code aus der android.provider.Contacts Klasse zusammengestellt:Ist dies eine Reflexion und in welchem ​​Maße?

Uri baseUri = Contacts.Phones.CONTENT_FILTER_URL; 

Wenn der 2.0 SDK herauskam, der Androide Die Klasse .provider.Contacts wurde abgeschrieben und durch android.provider.ContactsContract ersetzt. Um ein Programm zu erhalten sowohl auf 1,6 und 2,0 zu arbeiten, ich unter 1.6 mit folgenden Änderung zusammengestellt:

Uri baseUri = Contacts.Phones.CONTENT_FILTER_URL; 
… 
try { 
    Class<?> c = Class.forName("android.provider.ContactsContract$PhoneLookup"); 
    baseUri = (Uri) c.getField("CONTENT_FILTER_URI").get(baseUri); 
} 
    catch (Exception e) {   
} 

Da ich unter 1.6 wurde kompilieren, kann ich nicht importieren android.provider.ContactsContract da es ein Klasse nur bis 2.0 bekannt. Ist dies eine Reflexion und in welchem ​​Maße?

Kommentar hinzugefügt: Nach dem Lesen des "Reflection" -Kapitels von "The Java Programming Language" (was ich zuerst hätte tun sollen), verstehe ich jetzt meistens, was man mit Reflektion tun kann, aber eine präzise Definition von Reflektion nicht leicht zu kommen. Ihre Antworten haben dazu beigetragen, zu verdeutlichen, was meine Frage ausgelöst hat: Sobald eine Klasse reflektiert wurde und eine Instanz der Klasse, die mit Reflektion erstellt wurde, können Sie so mit der Instanz interagieren, als ob die Klasse neu ist.

Hier ist mein dürftiger Versuch einer knappe Definition, die bei weitem nicht perfekt und ich bin sicher, ich muß zu überarbeiten, wie ich mehr lernen:

Reflexion ist die indirekte, dynamische Untersuchung, Manipulation oder Aufruf von Klassenobjekten Verwenden von Klassenobjekten, die in java.lang.reflect oder den Class- oder Package-Klassen enthalten sind und die zunächst den Zugriff auf die Klasse mithilfe eines vollständig qualifizierten Zeichenfolgennamens erfordern.

+3

Beachten Sie, dass auch wenn die URI in 2.0 ist veraltet, Die Funktionalität sollte noch eine Weile im Framework bestehen (obwohl Android manchmal eine eigene Interpretation des Wortes "deprecated" hat). –

+0

Sie haben Recht, dass es immer noch existiert, außer dass die Funktionalität unter 2.0 nicht funktioniert. Der angeforderte Kontakt wird nicht zurückgenommen.Ich kann mich nicht erinnern, ob es jedes Mal Kontakt oder den Kontakt "Meine Kontaktkarte" zurückgibt. – fupsduck

+0

Anstelle des oben genannten Codes und mit einer ClassNotFound-Ausnahme können Sie proaktiv überprüfen, welche Edition von Android-Code durch eine Umgebungseigenschaft ausgeführt wird, und dann eine Unterfunktion aufrufen, die ein BaseURI zurückgibt –

Antwort

6

Ich glaube, das ist die Definition von Java reflection (more on Android reflection for multiple-version compatibility). Ich bin nicht sicher, was Sie mit "in welchem ​​Grad" meinen; es ist einfach so.

+0

richtig - entweder ist es oder es ist nicht. In diesem Fall ist es. – nont

+0

Bis zu welchem ​​Grad meine ich, dass alles da ist, um zu reflektieren? JasperE sagt, mein Beispiel sei nur eine Form, die impliziert, dass es mehr zu reflektieren gibt, als einfach "dynamisch nach der Verfügbarkeit einer Methode zu fragen". – fupsduck

+0

Nun, es gibt mehr Dinge, die man mit Reflektion tun kann, wie zum Beispiel das Erstellen von Objekten oder das Aufrufen von Methoden. Sie könnten Reflektion auch verwenden, um herauszufinden, welche Membervariablen und Klassenmethoden eine Klasse hat. –

4

Dynamisch nach der Verfügbarkeit einer Methode zu fragen ist eine Form der Reflexion, ja.

+0

Unter dem Strich, wann immer Sie Objekte mit ihren vollqualifizierten Namen aufrufen, ist das eine Reflektion, aber es gibt andere Formen der Reflektion? – fupsduck

+0

Nop. Reflection greift auf Typobjekte von Strings oder anderen Werttypen zu. Dies ist der Fall, wenn Sie den Namen der Klasse oder Methode in einer String-Variablen speichern und abrufen können. Es ist eine Reflektion, weil der Compiler den Wert dieser Variablen nicht kennt/prüft. – helios

+0

Oder vielleicht reflection = Zugriff auf Typinformationen zur Laufzeit. – helios

1

Es ist Reflexion. Wenn CONTENT_FILTER_URI ein endgültiges statisches Feld ist, sollten Sie get(null) anstelle von get(baseUri) verwenden, da Sie kein Objekt aufrufen.

bearbeiten

ich von Ihrem Code ein bisschen verwirrt war. Wie ich Ihr Schnipsel verstehe, zuerst Sie Contacts.Phones.CONTENT_FILTER_URL zu URL baseUri zuweisen, dann spiegeln Sie die CONTENT_FILTER_URI Feld auf der PhoneLookup Klasse und lesen Sie diese Felder Wert aus der URL Instanz in baseUri gespeichert - nur um den Wert wieder baseUri zuweisen!? Tippfehler oder Raum für Verbesserungen?

+0

Die Art, wie ich es verstehe, ist, dass die anfängliche Zuweisung benötigt wird, wenn das Programm unter 1.6 ausgeführt wird und die reflektierte Zuweisung benötigt wird, wenn es unter 2.0 ausgeführt wird. Da eine Exception unter 2.0 ausgelöst wird, gilt die ursprüngliche Zuweisung, wenn sie unter 1.6 ausgeführt wird. – fupsduck

+0

Typ - Die Ausnahme wird unter 1.6 nicht 2.0 ausgelöst, da die Klasse android.provider.ContactsContract nicht unter 1.6 existiert. – fupsduck

+0

Typ - über = Typo im ersten Kommentar. – fupsduck

Verwandte Themen