簡體   English   中英

將Bundle的內容打印到Logcat?

[英]Print the contents of a Bundle to Logcat?

如果您不記得所有鍵的名稱(即使只打印鍵名也會很酷),是否有一種簡單的方法可以將Bundle的內容打印到 Logcat?

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 附加功能),您很可能不會從打印輸出中獲得任何有用的信息。

您可以通過按如下方式打印映射值來獲得更具體的信息:

for (String key : bundle.keySet())
{
    Log.d("Bundle Debug", key + " = \"" + bundle.get(key) + "\"");
}

捆綁到字符串轉換器:

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

請注意箭頭=>和分號; 讓您在鍵和值中提及空格。 箭頭前一個空格,箭頭后一個空格,分號前沒有空格,分號后一個空格, {后一個空格, }前一個空格,所有其他空格都在那里,因為它們在鍵中或價值觀。

意識到這並不能准確回答問題,但我看到很多開發人員試圖將內容轉儲到 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 類型的變量的斷點,您將在調試器窗口的變量部分看到上述代碼生成的輸出。

我還將包括一個屏幕截圖,顯示我上面描述的內容...... 截屏

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

Kotlin 中簡單的 Bundle to String 實現:

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

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

技巧:訪問 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]

我開發了一個名為pretty-print的庫,它的注釋處理器以漂亮的表格格式打印包的內容。 請檢查一下https://github.com/NULLPointerGuy/pretty-print

Kotlin 解決方案:

val bundleFromNotifications: Bundle? = remoteMessage?.toIntent()?.extras
bundleFromNotifications?.keySet()?.forEach{
    Log.d(LOG_TAG, it + "=> \"" + bundleFromNotifications.get(it) + "\"")
}

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

請注意,它不能處理所有可能類型的值。 您應該決定展示哪些重要內容以及展示方式。

Java 8 流式一班輪:

bundle.keySet().stream().forEach(k -> Log.d(TAG, k + " = " + bundle.get(k)));

科特林

如果你有簡單Bundle s(沒有嵌套的 bundles),那么Jerry101的提示已經讓你走得很遠(請參閱他們的評論為什么這樣做)。 這是一個單行:

Log.d(TAG, "bundle: ${bundle?.also { it.keySet() }?: "N/A"}")

以上打印:

捆綁:捆綁[{a = 42,s =你好,...}]

或者當 bundle 為null時:

捆綁:不適用

如果您不確定上述內容是否始終有效,則代碼稍多一點,幾乎相同(使用此處其他人已經指出的keySet函數)-還有一行:

Log.d(TAG, "bundle: ${bundle?.keySet()?.associateWith { bundle[it] }?: "N/A"}")

這會將捆綁包轉換為地圖並打印

捆綁:{a=42,s=你好,...}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM