2016-05-26 7 views
23

Gibt es eine einfache Möglichkeit, eine Map in ein Android-Paket ohne explizite Iteration zu konvertieren?Karte in Bündel in Android konvertieren

Warum?

Firebase gibt eine Karte zur Benachrichtigung getData() zurück. Ich muss die Daten zu einer Absicht weitergeben. Früher gab mir GCM ein Bündel, also musste ich mir darüber keine Sorgen machen.

+3

"Gibt es eine einfache Möglichkeit, eine Map in ein Android-Paket ohne explizite Iteration zu konvertieren?" - Beachten Sie, dass eine 'Map' nicht unbedingt mit einem' Bundle' gleichzusetzen ist. Eine 'Map' kann Schlüssel haben, die keine Zeichenketten sind. Eine Map kann Werte enthalten, die nicht zu den unterstützten Datentypen gehören. – CommonsWare

+1

Ja, aber in meinem Fall sind sie alle Primitiven und String –

+0

Sie könnten es serialisieren. – cyroxis

Antwort

26

ich eine gute altmodische for-Schleife erraten ist der einfachste Weg:

Bundle bundle = new Bundle(); 
    for (Map.Entry<String, String> entry : getData().entrySet()) { 
     bundle.putString(entry.getKey(), entry.getValue()); 
    } 
+0

In meinem Fall ist das so gut wie es geht, nehme ich an. –

+2

Dies wird wahrscheinlich eine Ausnahme auslösen, weil der erste Parameter "google_sent_time" einen langen Typ hat und Sie 'putString' verwenden. Sie verwenden besser die Absicht, die Typvariation für Sie zu handhaben, und verwenden 'intent.putExtra (entry.getKey(), entry.getValue())', so dass verschiedene Datentypen für Sie kein Problem darstellen. –

-2
private ArrayList<Bundle> convertMapToBundleList(ArrayList<HashMap<String, String>> mapList) 
+0

Bitte aktualisieren und erklären Sie Ihre Antwort. –

1

Sie writeToParcel(Parcel out, int flags) verwenden können eine Parcel zu erzeugen, die in ähnlicher Weise nützlich sein könnte, da es sich um eine übergeordnete Klasse von Bundle ist, und Es ist praktisch in das Firebase-Framework als Teil der Klasse RemoteMessage integriert. Dokumentation ist here.

+0

'Parcel' ist eine Superklasse von' Bundle', und obwohl es ähnlich nützlich sein kann, können sie nicht synonym verwendet werden. –

+0

Ja, ich habe erwähnt, dass es die Elternklasse ist. – SQLiteNoob

4

Kam zu dem gleichen Problem mit Firebase Messaging und erstellt eine Kotlin-Erweiterung-Funktion für sie. Der gist is here, Code unten. Obwohl ich diese Methode dort bin mit ein paar Einschränkungen:

  • es alle Typen nicht abdecken, die in ein Bündel gesetzt werden kann
  • es ist noch in der Entwicklung und wurde nicht vollständig getestet

In diesem Sinne, bitte verwenden Sie es als Leitfaden nicht als endgültige Lösung. Ich werde das Wesentliche auf dem neuesten Stand halten, wie es sich entwickelt.

import android.os.Bundle 
import android.os.IBinder 
import android.os.Parcelable 
import java.io.Serializable 

fun <V> Map<String, V>.toBundle(bundle: Bundle = Bundle()): Bundle = bundle.apply { 
    forEach { 
    val k = it.key 
    val v = it.value 
    when (v) { 
     is IBinder -> putBinder(k, v) 
     is Bundle -> putBundle(k, v) 
     is Byte -> putByte(k, v) 
     is ByteArray -> putByteArray(k, v) 
     is Char -> putChar(k, v) 
     is CharArray -> putCharArray(k, v) 
     is CharSequence -> putCharSequence(k, v) 
     is Float -> putFloat(k, v) 
     is FloatArray -> putFloatArray(k, v) 
     is Parcelable -> putParcelable(k, v) 
     is Serializable -> putSerializable(k, v) 
     is Short -> putShort(k, v) 
     is ShortArray -> putShortArray(k, v) 

//  is Size -> putSize(k, v) //api 21 
//  is SizeF -> putSizeF(k, v) //api 21 

     else -> throw IllegalArgumentException("$v is of a type that is not currently supported") 
//  is Array<*> -> TODO() 
//  is List<*> -> TODO() 
    } 
    } 
} 
+0

noch nie von Kotlin vor heute gehört; interessanter Fund – CCJ