Wenn ich in meiner Anwendung eine Aktivitätsklasse namens TestActivity habe, gibt es eine Möglichkeit, die Klasse anhand ihres Namens wie in diesem Beispiel zu ermitteln:
Sie müssen auch den vollständigen Paketnamen angeben. Beispiel: com.bla.TestActivity als Argument für Class.forName
Richie
1
Können Sie auch etwas tun, um zu erhalten Class<? extends SomeClass>?
Gobliins
@Gobliins Nein - der Compiler kann nicht garantieren, welche Art von Klasse Sie erhalten werden, daher gibt er Ihnen eine Klasse <?>. Wenn Sie wissen, welche Art von Klasse Sie erhalten werden, müssen Sie sie wirken (trotzdem erhalten Sie ungeprüfte Warnungen, weil die Besetzung nicht sicher ist).
Dylanthepiguy
@Gobliins Schauen Sie sich meine Antwort an, wie Sie eine Unterklasse eines bestimmten Typs erhalten.
Raphinesse
6
Sie können verwenden Class::forName, um ein Klassenobjekt unbekannten Typs abzurufen. Wenn Sie eine typisierte Klasse erhalten möchten, können Sie diese Class::asSubclassfür folgende Klasse verwenden Class::forName:
Die übliche Methode für SO, so zu antworten, besteht darin , ihre Antwort zu bearbeiten . Obwohl es in Java zahlreiche Ausnahmen gibt (und Ihr Code dies einfach ignoriert), würde ein Kommentar ausreichen, um dies zu beheben.
crazyhatfish
7
@crazyhatfish - Es scheint, als hätte Patrick möglicherweise nicht die Privilegien gehabt, etwas Hilfreiches zu tun, außer seine eigene Antwort zu posten.
Amess
3
@amess Whoops, dein Recht, ich vergesse Kommentare brauchen rep. Danke, dass du mich verbessert hast.
crazyhatfish
2
Ich hatte auch eine ähnliche Anforderung, ich hatte einen JSON aus dem Backend, der den Bildschirm und die Aktivitätszuordnung enthält. Da der JSON für iOS / Android gemeinsam ist, konnten wir dem JSON keine Begriffe wie hinzufügen Activity, also haben wir dies getan
Verwenden Sie in json für alle Activityoder Viewcontrollerseinfache Namen, dh für HomeActivityund HomeViewControllerwir verwenden "Home" im json
In der App analysieren wir den JSON und ich habe die folgenden Dienstprogrammmethoden geschrieben, um die Aktivität dynamisch abzurufen
Um den Namen der Klasse zu erhalten (dh wenn wir nach Hause kommen, werden wir zurückkommen com.package.HomeActivity)
fun getClassInfoFor(name: String, context: Context):String{
var str = "${context.getPackageName()}.${name}Activity"return str
}
Nun, um Klasse aus String zu bekommen
try {
val className = Utilties.getClassInfoFor(activityNameFromJSON, context)
val fetchedClass = Class.forName(className)
val showDetailsIntent = Intent(context, fetchedClass)
context.startActivity(showDetailsIntent)
} catch (e: ClassNotFoundException) {
e.printStackTrace()
}
Auf diese Weise kann ich problemlos mehrere Klassen mit derselben Methode verwalten. Ich verwende dies in einer Recycler-Ansicht, in der jede Zelle zu einer anderen Aktivität navigiert.
Bitte beachte, dass deine Antwort in Kotlin ist;) Ändere sie wahrscheinlich ein wenig, um sie zu Java zu machen?
LMD
@LMD wahrscheinlich brauchen die meisten Android-Entwickler, die nach einer Antwort suchen, die Kotlin-Version, nicht Java;)
Ruslan Berozov
@ RuslanBerozov Die Operation hat die Frage als [Java] markiert, daher würde ich mindestens eine Java-Version erwarten (zusätzliches Kotlin ist natürlich auch in Ordnung).
LMD
@LMD sorry, aber op hat 2012 eine Frage gestellt. Es ist wirklich schwer vorstellbar, dass er zu dieser Zeit von Kotlin wusste. Der Punkt ist, dass die Frage auch als [android] markiert ist, und heutzutage erwarte ich vorzugsweise die Kotlin-Version.
Ruslan Berozov
-2
Es ist möglicherweise nicht die relevanteste Antwort auf Ihre Frage, aber es ist im Allgemeinen schlecht, Klassennamenliterale als Zeichenfolgen fest zu codieren. Es könnte besser sein, zu verwenden
Class<? extends SomeClass>
?Sie können verwenden
Class::forName
, um ein Klassenobjekt unbekannten Typs abzurufen. Wenn Sie eine typisierte Klasse erhalten möchten, können Sie dieseClass::asSubclass
für folgende Klasse verwendenClass::forName
:Class<? extends Activity> activityClass = Class.forName("com.example.TestActivity") .asSubclass(Activity.class);
Natürlich müssen Sie auch eine Reihe verschiedener Arten von Ausnahmen behandeln. Wie beim Umgang mit Reflexion üblich.
quelle
Die Class.forName scheint Ausnahmen zu haben. Dies dient nur dazu, das oben Gesagte zu erweitern, um dieses Problem zu beheben.
try { t = Class.forName("com.package.classname"); } catch (Exception ignored){}
quelle
Ich hatte auch eine ähnliche Anforderung, ich hatte einen JSON aus dem Backend, der den Bildschirm und die Aktivitätszuordnung enthält. Da der JSON für iOS / Android gemeinsam ist, konnten wir dem JSON keine Begriffe wie hinzufügen
Activity
, also haben wir dies getanVerwenden Sie in json für alle
Activity
oderViewcontrollers
einfache Namen, dh fürHomeActivity
undHomeViewController
wir verwenden "Home" im jsonIn der App analysieren wir den JSON und ich habe die folgenden Dienstprogrammmethoden geschrieben, um die Aktivität dynamisch abzurufen
Um den Namen der Klasse zu erhalten (dh wenn wir nach Hause kommen, werden wir zurückkommen
com.package.HomeActivity
)fun getClassInfoFor(name: String, context: Context):String{ var str = "${context.getPackageName()}.${name}Activity" return str }
Nun, um Klasse aus String zu bekommen
try { val className = Utilties.getClassInfoFor(activityNameFromJSON, context) val fetchedClass = Class.forName(className) val showDetailsIntent = Intent(context, fetchedClass) context.startActivity(showDetailsIntent) } catch (e: ClassNotFoundException) { e.printStackTrace() }
Auf diese Weise kann ich problemlos mehrere Klassen mit derselben Methode verwalten. Ich verwende dies in einer Recycler-Ansicht, in der jede Zelle zu einer anderen Aktivität navigiert.
quelle
Es ist möglicherweise nicht die relevanteste Antwort auf Ihre Frage, aber es ist im Allgemeinen schlecht, Klassennamenliterale als Zeichenfolgen fest zu codieren. Es könnte besser sein, zu verwenden
Syntax.
quelle