LinkedList setzen in Intent extra wird bei ArrayList bei der Wiederherstellung in der nächsten Aktivität umgestaltet

Ein Verhalten, das ich beobachte, wenn ich serialisierbare Daten als Absicht extra vergisst, ist ziemlich seltsam, und ich wollte nur klären, ob es etwas gibt, an dem ich nicht verpasse.

Also das, was ich versuchte zu tun ist, dass in ActivtyA Ich habe eine LinkedList Instanz in die intent ich für den Start der nächsten Aktivität – ActivityB .

  • So stellen Sie den Photosphären-Modus ein, wenn Sie das Panorama öffnen
  • Wie kann ich die neue Absicht in onNewIntent () erfassen?
  • Starten Sie eine Anwendung von einer anderen Anwendung auf Android
  • Öffnen Sie eine andere Anwendung von Ihrem eigenen (Absicht)
  • USER_PRESENT Absicht für GO Locker
  • Android: App-Name von Absicht erhalten
  •  LinkedList<Item> items = (some operation); Intent intent = new Intent(this, ActivityB.class); intent.putExtra(AppConstants.KEY_ITEMS, items); 

    Im onCreate of ActivityB ich versucht, die LinkedList extra wie folgt LinkedList

     LinkedList<Item> items = (LinkedList<Item>) getIntent() .getSerializableExtra(AppConstants.KEY_ITEMS); 

    Als ich das ClassCastException , bekam ich immer wieder eine ClassCastException in ActivityB , in der obigen Zeile. Grundsätzlich sagte die Ausnahme, dass ich eine ArrayList . Sobald ich den Code oben geändert habe, um eine ArrayList stattdessen zu erhalten, funktionierte alles ganz gut.

    Jetzt kann ich nicht einfach herausfinden, aus der vorhandenen Dokumentation, ob dies das erwartete Verhalten auf Android bei der Übergabe serialisierbare List-Implementierungen ist. Oder vielleicht gibt es etwas grundsätzlich falsch, was ich tue.

    Vielen Dank.

  • Übertragen von Daten von einer Aktivität zu einer anderen Aktivität mit Intents
  • Wie füge ich Text auf Videoaufnahme hinzu?
  • Android Intents: Starten Sie die Aktivität mit dem Klassennamen aus einer anderen App, die dieselbe sharedUserId hat
  • Android-Empfänger für mehrere Aktionen?
  • Android tiefe Verknüpfung in eine App
  • Wie kann man ein Video auf Vollbildschirm im YouTube-Player spielen?
  • One Solution collect form web for “LinkedList setzen in Intent extra wird bei ArrayList bei der Wiederherstellung in der nächsten Aktivität umgestaltet”

    Ich kann dir sagen, warum das passiert, aber du wirst es nicht mögen 😉

    Zuerst ein bisschen Hintergrundinformationen:

    Extras in einer Intent sind im Grunde ein Android- Bundle die im Grunde ein HashMap von Schlüssel / Wert-Paare ist. Also wenn du so etwas machst

     intent.putExtra(AppConstants.KEY_ITEMS, items); 

    Android erstellt ein neues Bundle für die Extras und fügt einen Karteneintrag zum Bundle wo der Schlüssel AppConstants.KEY_ITEMS und der Wert Elemente ist (was Ihr LinkedList-Objekt ist).

    Das ist alles in Ordnung und gut, und wenn du das Extras Bündel LinkedList , nachdem dein Code ausgeführt wird, findest du, dass es eine LinkedList enthält. Jetzt kommt der interessante Teil …

    Wenn Sie startActivity() mit der Extras-enthaltenden Intent aufrufen, muss Android die Extras aus einer Karte von Schlüssel / Wert-Paaren in einen Byte-Stream konvertieren. Grundsätzlich muss es das Bündel serialisieren . Es muss das tun, weil es die Aktivität in einem anderen Prozess starten kann und um dies zu tun, muss es die Objekte im Bundle serialisieren / deserialisieren, damit es sie im neuen Prozess neu erstellen kann. Es muss auch dies tun, weil Android den Inhalt der Absicht in einigen Systemtabellen speichert, damit es die Absicht regenerieren kann, wenn es später benötigt wird.

    Um das Bundle in einen Byte-Stream zu serialisieren, geht es durch die Karte im Bündel und bekommt jedes Key / Value-Paar. Dann dauert es jeden "Wert" (das ist eine Art von Objekt) und versucht zu bestimmen, welche Art von Objekt ist es so, dass es es serialisieren kann in der effizientesten Weise. Dazu prüft er den Objekttyp gegen eine Liste bekannter Objekttypen . Die Liste der "bekannten Objekttypen" enthält Dinge wie Integer , Long , String , Map , Bundle und leider auch List . Wenn also das Objekt eine List (von der es viele verschiedene Arten gibt, einschließlich LinkedList ), serialisiert es es und markiert es als ein Objekt vom Typ List .

    Wenn das Bundle deserialisiert ist, dh: wenn du das machst:

     LinkedList<Item> items = (LinkedList<Item>) getIntent().getSerializableExtra(AppConstants.KEY_ITEMS); 

    Es erzeugt eine ArrayList für alle Objekte im Bundle des Typs List .

    Es gibt nicht wirklich alles, was du tun kannst, um dieses Verhalten von Android zu ändern. Zumindest jetzt weißt du, warum es das tut.

    Nur so dass du weißt: Ich habe eigentlich ein kleines Testprogramm geschrieben, um dieses Verhalten zu überprüfen und ich habe den Quellcode für Parcel.writeValue(Object v) der die Methode ist, die von Bundle aufgerufen wird, wenn sie die Map in ein Byte konvertiert Strom.

    Wichtiger Hinweis: Da List eine Schnittstelle ist, bedeutet dies, dass jede Klasse, die eine List implementiert, die du in ein Bundle steckst, als ArrayList herauskommt. Es ist auch interessant, dass Map auch in der Liste der "bekannten Objekttypen" steht, was bedeutet, dass egal welche Art von Map Objekt Sie in ein Bundle (zB TreeMap , SortedMap oder jede Klasse, die die Map Schnittstelle implementiert), Sie Bekomme immer eine HashMap aus ihm heraus.

    Das Android ist ein Google Android Fan-Website, Alles über Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.