web-dev-qa-db-fra.com

Obtenir la classe par son nom

Si j'ai une classe d'activité appelée TestActivity dans mon application, existe-t-il un moyen d'obtenir sa classe par son nom, comme dans cet exemple:

Class<?> c = getClassByName("TestActivity");
73
Urho

utilisez forName à la place ..

quelque chose comme ça..

 try {
    Class<?> act = Class.forName("com.bla.TestActivity");
 } catch (ClassNotFoundException e) {
        e.printStackTrace();
}
140
ngesh

Le Class.forName semble avoir des exceptions. Ceci est juste pour développer ce qui précède pour résoudre ce problème.

try { t = Class.forName("com.package.classname"); } catch (Exception ignored){}
5
Patrick

Vous pouvez utiliser Class::forName pour obtenir un objet de classe de type inconnu. Si vous voulez obtenir une classe dactylographiée, vous pouvez utiliser Class::asSubclass sur la classe retournée par Class::forName:

Class<? extends Activity> activityClass = Class.forName("com.example.TestActivity")
                                               .asSubclass(Activity.class);

Bien entendu, vous devrez également gérer un grand nombre d'exceptions différentes. Comme d'habitude en matière de réflexion.

4
raphinesse

J'ai également eu une exigence similaire, j'avais un json venant de backend qui contient l'écran et la cartographie d'activité. Depuis le json en commun pour iOS/Android, nous ne pouvions pas ajouter des termes comme Activity dans le json, c'est donc ce que nous avons fait

  1. Dans json pour tous Activity ou Viewcontrollers, utilisez des noms simples, c.-à-d. Pour HomeActivity et HomeViewController, nous utiliserons "Home" dans le json

  2. Dans l'application, nous analysons le json et j'ai écrit les méthodes utilitaires ci-dessous pour obtenir l'activité dynamiquement

Pour obtenir le nom de la classe (c’est-à-dire que si nous passons à la maison, nous reviendrons com.package.HomeActivity)

    fun getClassInfoFor(name: String, context: Context):String{
        var str = "${context.getPackageName()}.${name}Activity"
        return str
    }

Maintenant, pour obtenir la classe de la chaîne

        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 cette façon, je peux facilement gérer plusieurs classes avec la même méthode. J'utilise ceci dans une vue de recycleur où chacune de mes cellules mène à une activité différente.

1
anoop4real

Ce n'est peut-être pas la réponse la plus pertinente pour votre question, mais il est généralement mauvais de coder en dur les littéraux de nom de classe en tant que chaînes. Il pourrait être préférable d'utiliser

Class<?> act = TestActivity.class;

syntaxe.

0
Krivda