Musisz również podać pełną nazwę pakietu. np. com.bla.TestActivity jako argument Class.forName
Richie
1
Czy możesz też coś zrobić, aby otrzymać Class<? extends SomeClass>?
Gobliins,
@Gobliins Nie - kompilator nie może zagwarantować, jaką klasę otrzymasz, więc podaje Ci klasę <?>. Jeśli wiesz, jaką klasę zdobędziesz, będziesz musiał ją rzucić (nawet nadal otrzymujesz niesprawdzone ostrzeżenia, ponieważ rzucanie nie jest bezpieczne).
Dylanthepiguy
1
@Gobliins Sprawdź moją odpowiedź, jak uzyskać podklasę określonego typu.
raphinesse
7
Możesz użyć, Class::forNameaby uzyskać obiekt klasy nieznanego typu. Jeśli chcesz uzyskać wpisaną klasę, możesz użyć Class::asSubclassna klasie zwróconej przez Class::forName:
Zwykłym sposobem udzielenia takiej odpowiedzi na SO jest edycja ich odpowiedzi. Chociaż w Javie jest mnóstwo wyjątków (a twój kod po prostu je ignoruje), komentarz byłby wystarczający, aby go rozwiązać.
tsn
7
@crazyhatfish - Wygląda na to, że Patrick mógł nie mieć przywilejów zrobienia czegokolwiek pomocnego poza zamieszczeniem własnej odpowiedzi.
amess
4
@amess Ups, masz rację, zapomniałem, że komentarze wymagają przedstawiciela. Dzięki za poprawienie mnie.
tsn
2
Miałem też podobny wymóg, miałem json pochodzący z zaplecza, który zawiera mapowanie ekranu i aktywności. Ponieważ json jest wspólny dla systemów iOS i Android, nie mogliśmy dodać takich terminów Activitydo json, więc to właśnie zrobiliśmy
W json dla wszystkich Activitylub Viewcontrollersużyj prostych nazw, tj. Dla HomeActivityi HomeViewControllerużyjemy „Home” w pliku json
W aplikacji analizujemy json i napisałem poniższe metody narzędziowe, aby dynamicznie uzyskać aktywność
Aby uzyskać nazwę klasy (tj. Jeśli miniemy Home, wrócimy com.package.HomeActivity)
fun getClassInfoFor(name: String, context: Context):String{
var str = "${context.getPackageName()}.${name}Activity"return str
}
Teraz, aby pobrać klasę ze stringa
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()
}
W ten sposób mogę łatwo zarządzać wieloma zajęciami za pomocą tej samej metody. Używam tego w widoku recyklera, w którym każda moja komórka kieruje się do innej czynności.
Zwróć uwagę, że twoja odpowiedź jest w Kotlinie;) Prawdopodobnie trochę ją zmodyfikuj, aby była Java?
LMD
@LMD Prawdopodobnie większość programistów Androida szukających odpowiedzi potrzebuje wersji kotlin, a nie java;)
Ruslan Berozov
@RuslanBerozov Operator oznaczył pytanie jako [java], więc spodziewałbym się przynajmniej wersji Java (oczywiście dodatkowy Kotlin też jest w porządku).
LMD
@LMD przepraszam, ale op zadał pytanie w 2012 roku. Naprawdę trudno sobie wyobrazić, że wiedział wtedy o Kotlinie. Chodzi o to, że pytanie jest również oznaczone jako [android], a obecnie oczekuję preferowanej wersji Kotlin.
Ruslan Berozov
-2
To może nie być najbardziej odpowiednia odpowiedź na twoje pytanie, ale generalnie źle jest zakodować na stałe literały nazw klas jako ciągi. Lepiej byłoby użyć
Class<? extends SomeClass>
?Możesz użyć,
Class::forName
aby uzyskać obiekt klasy nieznanego typu. Jeśli chcesz uzyskać wpisaną klasę, możesz użyćClass::asSubclass
na klasie zwróconej przezClass::forName
:Class<? extends Activity> activityClass = Class.forName("com.example.TestActivity") .asSubclass(Activity.class);
Oczywiście będziesz musiał również poradzić sobie z wieloma różnymi typami wyjątków. Jak zwykle w przypadku refleksji.
źródło
Class.forName wydaje się mieć na niej wyjątki. To jest tylko rozwinięcie powyższego, aby rozwiązać ten problem.
try { t = Class.forName("com.package.classname"); } catch (Exception ignored){}
źródło
Miałem też podobny wymóg, miałem json pochodzący z zaplecza, który zawiera mapowanie ekranu i aktywności. Ponieważ json jest wspólny dla systemów iOS i Android, nie mogliśmy dodać takich terminów
Activity
do json, więc to właśnie zrobiliśmyW json dla wszystkich
Activity
lubViewcontrollers
użyj prostych nazw, tj. DlaHomeActivity
iHomeViewController
użyjemy „Home” w pliku jsonW aplikacji analizujemy json i napisałem poniższe metody narzędziowe, aby dynamicznie uzyskać aktywność
Aby uzyskać nazwę klasy (tj. Jeśli miniemy Home, wrócimy
com.package.HomeActivity
)fun getClassInfoFor(name: String, context: Context):String{ var str = "${context.getPackageName()}.${name}Activity" return str }
Teraz, aby pobrać klasę ze stringa
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() }
W ten sposób mogę łatwo zarządzać wieloma zajęciami za pomocą tej samej metody. Używam tego w widoku recyklera, w którym każda moja komórka kieruje się do innej czynności.
źródło
To może nie być najbardziej odpowiednia odpowiedź na twoje pytanie, ale generalnie źle jest zakodować na stałe literały nazw klas jako ciągi. Lepiej byłoby użyć
składnia.
źródło