Mam aktywność, która po uruchomieniu potrzebuje dostępu do dwóch różnych ArrayLists. Obie listy są różnymi obiektami, które sam stworzyłem.
Zasadniczo potrzebuję sposobu, aby przekazać te obiekty do działania z zamiaru. Mogę użyć addExtras (), ale wymaga to klasy kompatybilnej z Parceable. Mogę sprawić, że moje zajęcia będą przekazywane do postaci szeregowej, ale jak rozumiem, spowalnia to program.
Jakie są moje opcje?
Czy mogę przekazać Enum?
Nawiasem mówiąc: czy istnieje sposób na przekazanie parametrów Konstruktorowi aktywności z zamiaru?
Odpowiedzi:
To stare pytanie, ale wszyscy nie wspominają, że Enumy są w rzeczywistości
Serializable
i dlatego można je idealnie dodać do Intencji jako dodatek. Lubię to:Sugestia użycia zmiennych statycznych lub obejmujących całą aplikację jest naprawdę złym pomysłem. To naprawdę łączy twoje działania z systemem zarządzania stanem i jest trudne do utrzymania, debugowania i problemów.
ALTERNATYWY:
Tedzyc zauważył , że rozwiązanie dostarczone przez Oderik daje błąd. Jednak oferowana alternatywa jest nieco kłopotliwa w użyciu (nawet przy użyciu generycznych).
Jeśli naprawdę martwisz się wydajnością dodawania wyliczenia do zamiaru, proponuję zamiast tego następujące alternatywy:
OPCJA 1:
Stosowanie:
OPCJA 2: (ogólna, wielokrotnego użytku i oddzielona od wyliczenia)
Stosowanie:
OPCJA 3 (z Kotlin):
Minęło trochę czasu, ale odkąd mamy Kotlina, pomyślałem, że dodam kolejną opcję dla nowego paradygmatu. Tutaj możemy skorzystać z funkcji rozszerzeń i typów zmienionych (które zachowują typ podczas kompilacji).
Jest kilka korzyści z robienia tego w ten sposób.
inline
czemu zastąpi wywołania kodem wewnątrz funkcji.Jedną z wad jest to, że jeśli zmienimy kolejność Emums, żadne stare odniesienie nie będzie działać. Może to być problem z rzeczami takimi jak intencje w toku, ponieważ mogą przetrwać aktualizacje. Jednak przez resztę czasu powinno być w porządku.
Ważne jest, aby pamiętać, że inne rozwiązania, takie jak użycie nazwy zamiast pozycji, również zawiodą, jeśli zmienimy nazwę dowolnej z wartości. Chociaż w takich przypadkach otrzymujemy wyjątek zamiast niepoprawnej wartości Enum.
Stosowanie:
źródło
enum class
typy na zwykłą Javęenum
. Wydaje mi się, że łatwiejszym obejściem jest zrobienieenum class
narzędziaSerializable
:enum class AwesomeEnum : Serializable { A, B, C }
nie idealne, ale powinno działać.Możesz zrobić implementację enum Parcelable, co jest dość łatwe dla enum:
Następnie możesz użyć Intent.putExtra (String, Parcelable).
AKTUALIZACJA: Proszę zwrócić uwagę na komentarz wreckgara, który
enum.values()
przydziela nowe tablice przy każdym wywołaniu.AKTUALIZACJA: Android Studio zawiera szablon na żywo,
ParcelableEnum
który implementuje to rozwiązanie. (W systemie Windows użyj Ctrl+ J)źródło
Możesz przekazać wyliczenie jako ciąg.
Podane łańcuchy są obsługiwane, powinieneś być w stanie bez problemu przekazać wartość wyliczenia.
źródło
Aby przekazać wyliczenie przez zamiar, możesz przekonwertować wyliczenie na liczbę całkowitą.
Dawny:
Wysyłanie (wyliczenie do liczby całkowitej):
Odbieranie (liczba całkowita do wyliczenia):
Z poważaniem. :)
źródło
Jeśli naprawdę potrzebujesz, możesz serializować wyliczenie jako ciąg, używając
name()
ivalueOf(String)
, w następujący sposób:To oczywiście nie działa, jeśli twoje wyliczenia mają stan zmienny (czego tak naprawdę nie powinny).
źródło
Może być możliwe, aby Twoje Enum zaimplementowało Serializowalny, a następnie możesz przekazać je poprzez Intent, ponieważ istnieje metoda przekazywania go jako szeregowalnego. Rada używania int zamiast enum jest fałszywa. Wyliczenia służą do ułatwienia odczytu i konserwacji kodu. Byłby duży krok wstecz w ciemne wieki, aby nie móc używać Enums.
źródło
na temat postu Oderika:
Jeśli zdefiniujesz zmienną MyEnum myEnum, a następnie zrób intent.putExtra („Parcelable1”, myEnum), otrzymasz komunikat „Metoda putExtra (String, Parcelable) jest niejednoznaczna dla typu błędu Intent”. ponieważ istnieje również metoda Intent.putExtra (String, Parcelable), a sam oryginalny typ Enum implementuje interfejs Serializable, więc kompilator nie wie, która metoda (intent.putExtra (String, Parcelable / or Serializable)).
Zaproponuj usunięcie interfejsu Parcelable z MyEnum i przeniesienie kodu podstawowego do implementacji klasy opakowywania „Parcelable”, takiej jak ta (Father2 jest Parcelable i zawiera pole enum):
wtedy możemy zrobić:
źródło
intent.putExtra("myEnum", (Parcelable) enumValue);
bundle.putExtra("key", AnotherEnum.X.ordinal())
.możesz użyć konstruktora enum dla enum, aby mieć prymitywny typ danych.
możesz użyć, aby przekazać int jako dodatki, a następnie wyciągnąć go z wyliczenia, używając jego wartości.
źródło
Większość odpowiedzi, które używają tutaj koncepcji Parcelable, znajduje się w kodzie Java. Łatwiej jest to zrobić w Kotlinie.
Po prostu adnotuj swoją klasę enum za pomocą @Parcelize i zaimplementuj interfejs Parcelable.
źródło
Lubię proste.
HAPPY
iSAD
.IntentFactory
który stworzyIntent
dla Ciebie. Podaj to,Mode
co chcesz.IntentFactory
Używa nazwyMode
klasy jako nazwa Extra.IntentFactory
przekształcaMode
się doString
korzystanianame()
onCreate
informacje te przekonwertować z powrotem naMode
.Można użyć
ordinal()
iMode.values()
jak dobrze. Lubię łańcuchy, ponieważ widzę je w debuggerze.źródło
Myślę, że najlepszym rozwiązaniem będzie przekonwertowanie tych list na paczkowate, takie jak ciąg znaków (lub mapa?), Aby przenieść je do działania. Następnie działanie będzie musiało przekonwertować go z powrotem na tablicę.
Wdrażanie niestandardowych paczek to ból w szyi IMHO, więc w miarę możliwości unikałbym tego.
źródło
Rozważ następujące wyliczenie:
Do zaliczenia:
Aby odzyskać z intencji / pakietu / argumentów:
źródło
Jeśli chcesz tylko wysłać wyliczenie, możesz zrobić coś takiego:
Najpierw zadeklaruj wyliczenie zawierające pewną wartość (którą można przekazać celowo):
Następnie:
A kiedy chcesz to zdobyć:
Bułka z masłem!
źródło
Użyj funkcji rozszerzenia Kotlin
Daje to elastyczność przekazywania wielokrotności tego samego typu wyliczenia lub domyślnego używania nazwy klasy.
źródło
Nie używaj enumów. Powód # 78, aby nie używać wyliczeń. :) Używaj liczb całkowitych, które można łatwo zdalnie przekazać za pomocą pakietu i paczki.
źródło
mEnum.ordinal()
? zwraca pozycję elementuEnum.ordinal()
jest ustalana w czasie kompilacji. Jedyny czas, w którym komentarz ma zastosowanie, to przekazywanie danych między aplikacjami z różnymi wersjami wyliczenia lub między aktualizacjami aplikacji, które zmieniają kolejność elementów w wyliczeniu. Tego rodzaju rzeczy są niebezpieczne, ilekroć używasz czegoś, co nie jest prymitywne. Przekazywanie zamiarów między czynnościami w ramach jednej aplikacjiEnum.ordinal()
powinno być całkowicie bezpieczne.