73

Bundle如果您不记得所有键的名称(即使只打印键名也会很酷),是否有一种简单的方法可以将 a 的内容打印到 Logcat?

4

11 回答 11

125

Bundle#keySet()应该可以工作。

for (String key: bundle.keySet())
{
  Log.d ("myApplication", key + " is a key in the bundle");
}

如果你想获得对象,你可以使用Bundle#get(String key)(这也在我在答案顶部链接的同一个文档中)。但是,请记住使用通用get()调用:

  • 您正在使用对象。如果您只是打印到日志,toString()将被调用,一切都会好起来的。但是,如果您真的想使用密钥对,则需要进行instanceof检查以避免调用错误的方法。
  • 因为 toString 将被调用,如果你有一个特殊的对象(例如 ArrayLists,或特殊的 Serializable/Parcelable extras),你很可能不会从打印输出中得到任何有用的东西。
于 2013-02-19T02:15:22.110 回答
41

您可以通过按如下方式打印映射值来获得更具体的信息:

for (String key : bundle.keySet())
{
    Log.d("Bundle Debug", key + " = \"" + bundle.get(key) + "\"");
}
于 2013-02-19T04:37:14.757 回答
23

捆绑到字符串转换器:

public static String bundle2string(Bundle bundle) {
    if (bundle == null) {
        return null;
    }
    String string = "Bundle{";
    for (String key : bundle.keySet()) {
        string += " " + key + " => " + bundle.get(key) + ";";
    }
    string += " }Bundle";
    return string;
}

示例用法:

Log.d(TAG,"details="+bundle2string(details));

和输出:

details=Bundle{ RESPONSE_CODE => 5; }Bundle

请注意,箭头=>和分号可;让您在键和值中提及空格。箭头前一个空格,箭头后一个空格,分号前没有空格,分号后一个空格,后{一个空格,前一个空格},所有其他空格都在那里,因为它们在键或值中.

于 2013-11-20T11:32:35.993 回答
10

意识到这并没有准确回答问题,但我看到很多开发人员试图将内容转储到 logcat/console,因为他们不知道他们可以在 Android Studio 调试器中设置以在调试时显示自定义对象渲染,当你达到了一个断点。在 Bundle 的情况下,您可以采用此处其他答案中显示的代码类型,并将其应用为自定义渲染器,这样您就不需要将转储通过管道传输到 logcat 和/或控制台。

(这些说明来自 Android Studio 3.1.3(2018 年 6 月)...

  1. 选择“文件”,然后选择“设置”菜单选项/子选项。
  2. 在左侧的“设置”对话框中,向下钻取并选择“构建、执行、部署”、“调试器”、“数据视图”、“Java 类型渲染器”。
  3. 对话框右侧显示“渲染器名称”,输入您希望与正在创建的渲染器标识的名称。
  4. 对话框右侧显示“将渲染器应用于类型对象”,输入“android.os.Bundle”。
  5. 在对话框的右侧,在“渲染节点时”部分下,选择“使用以下表达式:”单选按钮。
  6. 在下面的文本字段中,输入以下内容...
StringBuilder builder = new StringBuilder();
for (String key : ((android.os.Bundle)this).keySet()) {
    Object value = ((android.os.Bundle)this).get(key);
    builder.append("[");
    builder.append(key);
    builder.append("]=[");
    builder.append(value);
    builder.append("](");
    builder.append((value != null) ? value.getClass().getSimpleName() : "null");
    builder.append("), ");
}
return builder.toString();
  1. 按“应用”/“确定”按钮。

现在,当您运行您的应用程序时,您遇到了一个显示 android.os.Bundle 类型的变量的断点,您将在调试器窗口的变量部分看到上述代码生成的输出。

我还将包括一个屏幕截图,显示我上面描述的内容...... 截屏

于 2018-07-09T03:20:38.313 回答
6

在 Kotlin 中,当它包含子包时递归:

/**
 * Recursively logs the contents of a [Bundle] for debugging.
 */
fun Bundle.printDebugLog(parentKey: String = "") {
    if (keySet().isEmpty()) {
        Log.d("printDebugLog", "$parentKey is empty")
    } else {
        for (key in keySet()) {
        when (val value = this[key]) {
                is Bundle -> value.printDebugLog(key)
                is Array<*> -> Log.d("printDebugLog", "$parentKey.$key : ${value.joinToString()}")
                else -> Log.d("printDebugLog", "$parentKey.$key : $value")
            }
        }
    }
}

用法:myBundle.printDebugLog()

于 2018-05-23T12:34:47.487 回答
6

Kotlin 中简单的 Bundle to String 实现:

val bundleToString = bundle.keySet()
            .joinToString(", ", "{", "}") { key ->
                "$key=${bundle[key]}"
            }

结果示例{id=3, name="Jhon"}

于 2020-03-05T11:00:47.440 回答
1

我开发了一个名为pretty-printwhich annotation processor 的库,它以漂亮的表格格式打印包的内容。请检查一下 https://github.com/NULLPointerGuy/pretty-print

于 2018-03-27T03:11:49.747 回答
1

Kotlin 解决方案:

val bundleFromNotifications: Bundle? = remoteMessage?.toIntent()?.extras
bundleFromNotifications?.keySet()?.forEach{
    Log.d(LOG_TAG, it + "=> \"" + bundleFromNotifications.get(it) + "\"")
}
于 2019-04-17T18:41:31.910 回答
0

Kotlin 中的解决方案:

fun Bundle.toPrintableString(): String {
    val sb = StringBuilder("{")
    var isFirst = true
    for (key in keySet()) {
        if (!isFirst)
            sb.append(',')
        else
            isFirst = false
        when (val value = get(key)) {
            is Bundle -> sb.append(key).append(':').append(value.toPrintableString())
            else -> sb.append(key).append(':').append(value)
            //TODO handle special cases if you wish
        }
    }
    sb.append('}')
    return sb.toString()
}

样本:

    val bundle = Bundle()
    bundle.putString("asd", "qwe")
    bundle.putInt("zxc", 123)
    Log.d("AppLog", "bundle:${bundle.toPrintableString()}")

请注意,它不能处理所有可能类型的值。您应该决定展示哪些重要内容以及展示方式。

于 2019-10-06T10:10:55.637 回答
0

Java 8 流式一班轮:

bundle.keySet().stream().forEach(k -> Log.d(TAG, k + " = " + bundle.get(k)));
于 2020-04-11T17:41:53.217 回答
0

技巧:访问 Bundle 的内容以对其进行具体化,然后bundle.toString()将其元素格式化。

(我仅将其用于调试目的。)

AppWidgetProvider 中的示例,调用newOptions.keySet()

    @Override
    public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager,
            int appWidgetId, Bundle newOptions) {
        super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions);

        newOptions.keySet(); // <-- reify the Bundle so .toString() will elaborate
        Log.i(TAG, "*** WidgetOptionsChanged: " + newOptions);
    }

结果:

*** WidgetOptionsChanged: Bundle[{appWidgetMaxHeight=137, appWidgetCategory=1, appWidgetMaxWidth=603, appWidgetMinHeight=82, appWidgetMinWidth=338, appWidgetSizes=[338.0x137.5, 603.5x82.0]}]

比:

*** WidgetOptionsChanged: Bundle[mParcelledData.dataSize=408]
于 2022-03-01T19:10:03.713 回答