【问题标题】:Convert Map to Bundle in android在 android 中将 Map 转换为 Bundle
【发布时间】:2016-09-24 22:52:17
【问题描述】:

在没有显式迭代的情况下,有没有一种简单的方法可以在 android 中将 Map 转换为 Bundle?

为什么?

Firebase 返回通知 getData() 的映射。我需要将数据传递给意图。以前 GCM 给了我一个捆绑包,所以我不需要担心这个。

【问题讨论】:

  • “有没有一种简单的方法可以在 android 中将 Map 转换为 Bundle 而无需显式迭代?” -- 请注意Map 不一定等同于BundleMap 可以有不是字符串的键。 Map 的值可能不是受支持的数据类型之一。
  • 是的,但就我而言,它们都是原语和字符串
  • 你可以序列化它。
  • RemoteMessage 对象是可打包的,你可以直接在意图中发送它

标签: android firebase bundle firebase-cloud-messaging


【解决方案1】:

我想一个好的老式 for 循环是最简单的方法:

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

【讨论】:

  • 这可能会引发异常,因为第一个参数“google_sent_time”具有 Long 类型并且您使用的是 putString。您最好使用意图为您处理类型变化并使用intent.putExtra(entry.getKey(), entry.getValue()),因此不同的数据类型不会对您造成问题。
  • @AmirZiarati 我不认为这是真的了,RemoteMessage#getData() 现在返回一个Map&lt;String, String&gt;,不包括一堆内部值。
【解决方案2】:

使用扩展运算符的整洁 Kotlin 解决方案如下所示:

fun Map<String, Any?>.toBundle(): Bundle = bundleOf(*this.toList().toTypedArray())

【讨论】:

【解决方案3】:

在使用 firebase 消息传递时遇到了同样的问题,并为它创建了一个 kotlin 扩展函数。 gist is here,代码如下。虽然我使用的是这种方法,但有一些注意事项:

  • 它并未涵盖可以放入包中的所有类型
  • 它仍在开发中,尚未经过全面测试

考虑到这一点,请将其用作指导而非最终解决方案。随着它的发展,我会不断更新要点。

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()
    }
  }
}

【讨论】:

  • 在今天之前从未听说过 kotlin;有趣的发现
【解决方案4】:

现在你可以使用fun bundleOf(vararg pairs: Pair&lt;String, Any?&gt;)

【讨论】:

    【解决方案5】:

    您可以使用writeToParcel(Parcel out, int flags) 来生成同样有用的Parcel,因为它是Bundle 的父类,并且它作为RemoteMessage 类的一部分轻松内置到Firebase 框架中。文档是here

    【讨论】:

    • ParcelBundle 的超类,因此虽然它同样有用,但它们不能互换使用。
    • 是的,我确实提到它是它的父类。
    • 您的答案可能更好,但缺乏解释或示例使其变得更糟。
    【解决方案6】:

    这是我在 Kotlin 中的做法

    val bundle = Bundle()
    
    for (entry in data.entries)
        bundle.putString(entry.key, entry.value)
    

    【讨论】:

      【解决方案7】:

      供以后参考?

      将映射转换为字符串

        fun Map<String, String>.convertExtraMapToString(): String? {
          return keys.stream()
              .map { key: String -> "$key=" + this[key] }.collect(Collectors.joining(", ", "{", "}"))
      }
      

      将 String 转换为 Map 然后再转换为 Bundle

      fun String.convertExtraMapToBundle(): Bundle {
          return Arrays.stream(split(",".toRegex()).toTypedArray())
              .map { entry: String -> entry.split("=".toRegex()).toTypedArray() }
              .collect(Collectors.toMap(
                  { entry: Array<String> -> entry[0] }) { entry: Array<String> -> entry[1] }).let {
                  bundleOf(*it.toList().toTypedArray())
              }
      }
      

      【讨论】:

        【解决方案8】:
         private ArrayList<Bundle> convertMapToBundleList(ArrayList<HashMap<String, String>> mapList)
        

        【讨论】:

          猜你喜欢
          • 2020-01-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-07-29
          • 2016-04-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多