Ich habe eine Aktivität, die beim Start Zugriff auf zwei verschiedene ArrayLists benötigt. Beide Listen sind unterschiedliche Objekte, die ich selbst erstellt habe.
Grundsätzlich brauche ich eine Möglichkeit, diese Objekte aus einer Absicht an die Aktivität zu übergeben. Ich kann addExtras () verwenden, dies erfordert jedoch eine Parceable-kompatible Klasse. Ich könnte meine Klassen serialisierbar machen, aber so wie ich es verstehe, verlangsamt dies das Programm.
Was sind meine Optionen?
Kann ich eine Aufzählung bestehen?
Nebenbei: Gibt es eine Möglichkeit, Parameter aus einer Absicht an einen Aktivitätskonstruktor zu übergeben?
Antworten:
Dies ist eine alte Frage, aber jeder erwähnt nicht, dass Enums tatsächlich sind
Serializable
und daher perfekt zu einer Absicht als Extra hinzugefügt werden können. So was:Der Vorschlag, statische oder anwendungsweite Variablen zu verwenden, ist eine wirklich schlechte Idee. Dies koppelt Ihre Aktivitäten wirklich an ein Statusverwaltungssystem, und es ist schwierig, sie zu warten, zu debuggen und an Probleme zu binden.
ALTERNATIVEN:
Tedzyc hat einen guten Punkt in Bezug auf die Tatsache festgestellt , dass die von Oderik bereitgestellte Lösung einen Fehler liefert. Die angebotene Alternative ist jedoch etwas umständlich (auch bei Verwendung von Generika).
Wenn Sie sich wirklich Sorgen über die Leistung des Hinzufügens der Aufzählung zu einer Absicht machen, schlage ich stattdessen diese Alternativen vor:
OPTION 1:
Verwendung:
OPTION 2: (generisch, wiederverwendbar und von der Aufzählung entkoppelt)
Verwendung:
OPTION 3 (mit Kotlin):
Es ist schon eine Weile her, aber da wir jetzt Kotlin haben, dachte ich, ich würde eine weitere Option für das neue Paradigma hinzufügen. Hier können wir Erweiterungsfunktionen und reifizierte Typen verwenden (die den Typ beim Kompilieren beibehalten).
Es gibt einige Vorteile, wenn Sie dies so tun.
inline
wodurch die Aufrufe durch den Code innerhalb der Funktion ersetzt werden.Einer der Nachteile ist, dass, wenn wir die Reihenfolge der Emums ändern, eine alte Referenz nicht funktioniert. Dies kann ein Problem mit Dingen wie Absichten in ausstehenden Absichten sein, da diese Aktualisierungen überleben können. Für den Rest der Zeit sollte es jedoch in Ordnung sein.
Es ist wichtig zu beachten, dass andere Lösungen, wie die Verwendung des Namens anstelle der Position, ebenfalls fehlschlagen, wenn wir einen der Werte umbenennen. In diesen Fällen erhalten wir jedoch eine Ausnahme anstelle des falschen Enum-Werts.
Verwendung:
quelle
enum class
Typen zu einem einfachen Javaenum
. Ich denke, die einfachere Problemumgehung besteht darin, dasenum class
Gerät zu erstellenSerializable
:enum class AwesomeEnum : Serializable { A, B, C }
Nicht ideal, sollte aber funktionieren.Sie können Ihre Aufzählung Parcelable implementieren lassen, was für Aufzählungen recht einfach ist:
Sie können dann Intent.putExtra (String, Parcelable) verwenden.
UPDATE: Bitte beachten Sie den Kommentar von Wreckgar,
enum.values()
der bei jedem Aufruf ein neues Array zuweist .UPDATE: Android Studio bietet eine Live-Vorlage
ParcelableEnum
, die diese Lösung implementiert. (Verwenden Sie unter Windows Ctrl+ J)quelle
Sie können eine Aufzählung als Zeichenfolge übergeben.
Wenn Zeichenfolgen unterstützt werden, sollten Sie in der Lage sein, den Wert der Aufzählung problemlos weiterzugeben.
quelle
Um eine Aufzählung absichtlich zu übergeben, können Sie die Aufzählung in eine Ganzzahl umwandeln.
Ex:
Senden (Aufzählung zu Ganzzahl):
Empfangen (Ganzzahl zu Aufzählung):
Freundliche Grüße. :) :)
quelle
Wenn Sie es wirklich brauchen, können Sie eine Aufzählung wie folgt mit
name()
undvalueOf(String)
wie folgt serialisieren :Dies funktioniert offensichtlich nicht, wenn Ihre Aufzählungen einen veränderlichen Zustand haben (was sie eigentlich nicht sollten).
quelle
Möglicherweise können Sie Ihr Enum-Implementierungsprogramm serialisierbar machen, dann können Sie es über den Intent übergeben, da es eine Methode gibt, um es als serialisierbar zu übergeben. Der Rat, int anstelle von enum zu verwenden, ist falsch. Aufzählungen werden verwendet, um Ihren Code leichter lesbar und leichter zu pflegen. Es wäre ein großer Schritt zurück in die dunklen Zeiten, Enums nicht verwenden zu können.
quelle
über Oderiks Beitrag:
Wenn Sie eine MyEnum-Variable myEnum definieren und dann intent.putExtra ("Parcelable1", myEnum) ausführen, wird die Fehlermeldung "Die Methode putExtra (String, Parcelable) ist für den Typ Intent nicht eindeutig" angezeigt. Da es auch eine Intent.putExtra-Methode (String, Parcelable) gibt und der ursprüngliche 'Enum'-Typ selbst die Serializable-Schnittstelle implementiert, weiß der Compiler nicht, welche Methode (intent.putExtra (String, Parcelable / oder Serializable)) ausgewählt wurde.
Schlagen Sie vor, die Parcelable-Schnittstelle aus MyEnum zu entfernen und den Kerncode wie folgt in die Parcelable-Implementierung der Wrap-Klasse zu verschieben (Father2 ist ein Parcelable und enthält ein Aufzählungsfeld):
dann können wir tun:
quelle
intent.putExtra("myEnum", (Parcelable) enumValue);
bundle.putExtra("key", AnotherEnum.X.ordinal())
.Sie können den Enum-Konstruktor für Enum verwenden, um den primitiven Datentyp zu haben.
Sie können int als Extras übergeben und dann mit seinem Wert aus enum ziehen.
quelle
Die meisten Antworten, die hier das Paketkonzept verwenden, sind in Java-Code. In Kotlin ist das einfacher.
Kommentieren Sie einfach Ihre Enum-Klasse mit @Parcelize und implementieren Sie die Parcelable-Schnittstelle.
quelle
Ich mag einfach.
HAPPY
undSAD
.IntentFactory
, die IhreIntent
für Sie erstellt. Gib es weiter, wasMode
du willst.IntentFactory
verwendet den Namen desMode
Klasse als Namen des Extra.IntentFactory
konvertiert dasMode
in einString
usingname()
onCreate
verwenden Sie diese Informationen, um wieder in a zu konvertierenMode
.Sie könnten
ordinal()
undMode.values()
auch verwenden. Ich mag Strings, weil ich sie im Debugger sehen kann.quelle
Ich denke, Ihre beste Wette ist es, diese Listen in etwas Parzellierbares wie eine Zeichenfolge (oder eine Karte?) Zu konvertieren, um sie zur Aktivität zu bringen. Dann muss die Aktivität sie wieder in ein Array konvertieren.
Das Implementieren von benutzerdefinierten Paketen ist meiner Meinung nach ein Schmerz im Nacken, daher würde ich es nach Möglichkeit vermeiden.
quelle
Betrachten Sie folgende Aufzählung ::
Zum Bestehen ::
So rufen Sie die Absicht / das Bündel / die Argumente ab ::
quelle
Wenn Sie nur eine Aufzählung senden möchten, können Sie Folgendes tun:
Deklarieren Sie zuerst eine Aufzählung mit einem Wert (der absichtlich übergeben werden kann):
Dann:
Und wenn Sie es bekommen wollen:
Stück Kuchen!
quelle
Verwenden Sie Kotlin-Erweiterungsfunktionen
Dies gibt Ihnen die Flexibilität, mehrere gleiche Aufzählungstypen zu übergeben oder standardmäßig den Klassennamen zu verwenden.
quelle
Verwenden Sie keine Aufzählungen. Grund Nr. 78, keine Aufzählungen zu verwenden. :) Verwenden Sie Ganzzahlen, die einfach über Bundle und Parcelable entfernt werden können.
quelle
mEnum.ordinal()
? Es gibt die Position des Elements zurückEnum.ordinal()
wird zur Kompilierungszeit festgelegt. Der einzige Zeitpunkt, zu dem ein Kommentar gilt, ist die Weitergabe von Daten zwischen Apps mit unterschiedlichen Versionen der Aufzählung oder zwischen App-Updates, die die Reihenfolge der Elemente in der Aufzählung ändern. So etwas ist gefährlich, wenn Sie etwas verwenden, das nicht primitiv ist. Das Übergeben von Absichten zwischen Aktivitäten innerhalb einer einzelnen AppEnum.ordinal()
sollte absolut sicher sein.