También debe proporcionar el nombre completo del paquete. por ejemplo: com.bla.TestActivity como argumento para Class.forName
Richie
1
¿También puedes hacer algo para recibir Class<? extends SomeClass>?
Gobliins
@Gobliins No, el compilador no puede garantizar qué tipo de clase obtendrá, por lo que le da una Clase <?>. Si sabe qué tipo de clase va a recibir, tendrá que lanzarla (aún así, recibirá advertencias de lanzamiento sin marcar porque el yeso no es seguro).
Dylanthepiguy
@Gobliins Mira mi respuesta sobre cómo obtener una subclase de cierto tipo.
raphinesse
6
Puede usar Class::forNamepara obtener un objeto de clase de tipo desconocido. Si desea obtener una clase escrita, puede usarla Class::asSubclassen la clase devuelta por Class::forName:
La forma habitual en SO de responder así sería editar su respuesta. Aunque dado que las excepciones son abundantes en Java (y su código simplemente lo ignora), un comentario sería suficiente para abordarlo.
tsn
7
@crazyhatfish: parece que Patrick no ha tenido los privilegios de hacer nada útil excepto publicar su propia respuesta.
amess
3
@amess Vaya, tienes razón, olvido que los comentarios necesitan representante. Gracias por corregirme.
tsn
2
También tenía un requisito similar, tenía un json proveniente del backend que contiene la pantalla y el mapeo de actividades. Dado que el json es común para iOS / Android, no pudimos agregar términos como Activityen el json, así que esto es lo que hicimos
En json para todos Activityo Viewcontrollers, use nombres simples, es decir, para HomeActivityy HomeViewControllerusaremos "Inicio" en el json
En la aplicación, analizamos el json y he escrito los siguientes métodos de utilidad para obtener la actividad de forma dinámica
Para obtener el nombre de la clase (es decir, si pasamos a Inicio, volveremos com.package.HomeActivity)
fun getClassInfoFor(name: String, context: Context):String{
var str = "${context.getPackageName()}.${name}Activity"return str
}
Ahora para obtener la clase de la cadena
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()
}
De esta manera puedo administrar fácilmente varias clases con el mismo método. Utilizo esto en una vista de reciclador donde cada una de mis células navega hacia una actividad diferente.
Tenga en cuenta que su respuesta está en Kotlin;) ¿Probablemente la modifique un poco para que sea Java?
LMD
@LMD probablemente la mayoría de los desarrolladores de Android que buscan una respuesta necesitan la versión kotlin, no java;)
Ruslan Berozov
@RuslanBerozov El operador ha etiquetado la pregunta como [java], por lo que esperaría al menos una versión de Java (Kotlin adicional también está bien, por supuesto).
LMD
@LMD lo siento, pero op publicó una pregunta en 2012. Es realmente difícil imaginar que él sabía sobre Kotlin en ese momento. El punto es que la pregunta también está marcada como [android], y hoy en día espero la versión de Kotlin preferiblemente.
Ruslan Berozov
-2
Puede que no sea la respuesta más relevante para su pregunta, pero generalmente es malo codificar los literales de nombres de clases como cadenas. Podría ser mejor usar
Class<? extends SomeClass>
?Puede usar
Class::forName
para obtener un objeto de clase de tipo desconocido. Si desea obtener una clase escrita, puede usarlaClass::asSubclass
en la clase devuelta porClass::forName
:Class<? extends Activity> activityClass = Class.forName("com.example.TestActivity") .asSubclass(Activity.class);
Por supuesto, también tendrá que manejar un montón de tipos diferentes de excepciones. Como es habitual cuando se trata de reflexión.
fuente
El Class.forName parece tener excepciones. Esto es solo para ampliar lo anterior para abordar este problema.
try { t = Class.forName("com.package.classname"); } catch (Exception ignored){}
fuente
También tenía un requisito similar, tenía un json proveniente del backend que contiene la pantalla y el mapeo de actividades. Dado que el json es común para iOS / Android, no pudimos agregar términos como
Activity
en el json, así que esto es lo que hicimosEn json para todos
Activity
oViewcontrollers
, use nombres simples, es decir, paraHomeActivity
yHomeViewController
usaremos "Inicio" en el jsonEn la aplicación, analizamos el json y he escrito los siguientes métodos de utilidad para obtener la actividad de forma dinámica
Para obtener el nombre de la clase (es decir, si pasamos a Inicio, volveremos
com.package.HomeActivity
)fun getClassInfoFor(name: String, context: Context):String{ var str = "${context.getPackageName()}.${name}Activity" return str }
Ahora para obtener la clase de la cadena
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() }
De esta manera puedo administrar fácilmente varias clases con el mismo método. Utilizo esto en una vista de reciclador donde cada una de mis células navega hacia una actividad diferente.
fuente
Puede que no sea la respuesta más relevante para su pregunta, pero generalmente es malo codificar los literales de nombres de clases como cadenas. Podría ser mejor usar
sintaxis.
fuente