Bundle.get(key: String)
已弃用:
根据要检索的项目的类型使用类型安全的特定 API,例如。获取字符串(字符串)。
那么这个方法该如何解决呢?不要认为我可以在这里使用泛型 T,因为 Bundle 可以包含多种不同的类型。我觉得在检索之前我必须知道要检索的密钥的类型,这可能吗?
private fun Bundle.toMap(): Map<String?, *> {
val map = mutableMapOf<String?, Any?>()
for (key in keySet()) {
map[key] = get(key)
}
return map
}
也许有人可以深入研究更多细节,但我将在我们的项目中使用以下内容作为解决方法 - 也许它可以帮助某人。就我而言,我需要记录从第 3 方应用程序收到的完整捆绑包,而无需提前知道条目的确切类型。
使用以下内容作为测试输入:
val bundle = Bundle().apply {
putByte("typeByte", 0x01)
putShort("typeShort", 1234)
putInt("typeInt", 1234)
putLong("typeLong", 1234)
putChar("typeChar", 'C')
putString("typeString", "Test")
putBoolean("typeBoolean", true)
}
下一步,我将把这个
Bundle
转换为 Intent
- 及其 Uri
表示形式:
val intent = Intent().apply {
putExtras(bundle)
}
val uri = intent.toUri(Intent.URI_INTENT_SCHEME)
我的案例的这一部分会生成类似以下内容的内容(如果值中存在特殊字符,则可能需要首先使用
Uri.decode(uri)
):
"intent:#Intent;S.typeString=Test;i.typeInt=1234;b.typeByte=1;c.typeChar=C;l.typeLong=1234;s.typeShort=1234;B.typeBoolean=true;end"
在这里,我将字符串按
;
分割,并删除第一部分和最后一部分。使用我的辅助数据类:
data class BundleEntry(
val type: String,
val key: String,
val value: String
)
// drop first (intent:#Intent) and last (end) part
val asList = uri.split(";").drop(1).dropLast(1).map {
// "S.typeString=Test" part
val tmp = it.split(".") // "S" and "typeString=Test"
val tmp2 = tmp[1].split("=") // "typeString" and "Test"
BundleEntry(tmp[0], tmp2[0], tmp2[1])
}
作为原始问题的最后一部分,适当转换此
asList
中的值 - 这部分需要适应可能发生的每个 BundleEntry.type
,或者 String
部分中的 else
表示就足够了...
asList.forEach {
when (it.type) {
"S" -> map[it.key] = it.value
"i" -> map[it.key] = it.value.toInt()
"b" -> map[it.key] = it.value.toByte()
"c" -> map[it.key] = it.value[0]
"l" -> map[it.key] = it.value.toLong()
"s" -> map[it.key] = it.value.toShort()
"B" -> map[it.key] = it.value.toBoolean()
else -> {
Log.w("TAG", "unhandled bundle type \"${it.type}\"")
map[it.key] = it.value // as String
}
}
}
return map