【问题标题】:Convert a Bundle to JSON将 Bundle 转换为 JSON
【发布时间】:2014-02-18 15:42:30
【问题描述】:

我想将 Intent 的 extras Bundle 转换为 JSONObject,以便可以将其传递给 JavaScript。

有没有一种快速或最佳的方法来进行这种转换?如果不是所有可能的 Bundles 都可以工作,那也没关系。

【问题讨论】:

  • 你有什么额外的?
  • 我不打算处理特定的附加组件。我想要一些通用代码来执行此操作,因为此代码路径可以被我以外的其他开发人员用于任意数据。

标签: java android json android-intent


【解决方案1】:

您可以使用Bundle#keySet() 获取Bundle 包含的密钥列表。然后,您可以遍历这些键并将每个键值对添加到 JSONObject

JSONObject json = new JSONObject();
Set<String> keys = bundle.keySet();
for (String key : keys) {
    try {
        // json.put(key, bundle.get(key)); see edit below
        json.put(key, JSONObject.wrap(bundle.get(key)));
    } catch(JSONException e) {
        //Handle exception here
    }
}

请注意,JSONObject#put 将要求您捕获 JSONException

编辑:

有人指出,前面的代码没有很好地处理CollectionMap 类型。如果您使用的是 API 19 或更高版本,则有一个 JSONObject#wrap 方法可以帮助您,如果这对您很重要。来自docs

如有必要,包装一个对象。如果对象为空,则返回 NULL 目的。如果是数组或集合,则将其包装在 JSONArray 中。如果它 是一个地图,将它包装在一个 JSONObject 中。如果是标准属性 (Double, String, et al) 那么它已经被包装了。否则,如果它 来自其中一个 java 包,把它变成一个字符串。如果它 没有,请尝试将其包装在 JSONObject 中。如果包装失败,那么 返回 null。

【讨论】:

  • 这个实现似乎不能正确处理地图或列表。您应该检查从包中获取的对象的类型,如果是地图,则可以使用 new JSONObject(map) 构造函数,如果是列表,则可以使用 new JSONArray(list)
  • 好电话。如果您不想进行检查,还有一个 JSONObject#wrap 方法可以为您包装它。
  • 酷。我不知道这个功能的存在,这让它变得容易多了。
  • 刚刚注意到该功能仅在 android SDK 19 版中可用,但您可以从源代码中复制该功能。 android.googlesource.com/platform/libcore/+/master/json/src/…
  • 嘘。更新了答案以反映这一点。
【解决方案2】:
private String getJson(final Bundle bundle) {
    if (bundle == null) return null;
    JSONObject jsonObject = new JSONObject();

    for (String key : bundle.keySet()) {
        Object obj = bundle.get(key);
        try {
            jsonObject.put(key, wrap(bundle.get(key)));
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
    return jsonObject.toString();
}

public static Object wrap(Object o) {
    if (o == null) {
        return JSONObject.NULL;
    }
    if (o instanceof JSONArray || o instanceof JSONObject) {
        return o;
    }
    if (o.equals(JSONObject.NULL)) {
        return o;
    }
    try {
        if (o instanceof Collection) {
            return new JSONArray((Collection) o);
        } else if (o.getClass().isArray()) {
            return toJSONArray(o);
        }
        if (o instanceof Map) {
            return new JSONObject((Map) o);
        }
        if (o instanceof Boolean ||
                o instanceof Byte ||
                o instanceof Character ||
                o instanceof Double ||
                o instanceof Float ||
                o instanceof Integer ||
                o instanceof Long ||
                o instanceof Short ||
                o instanceof String) {
            return o;
        }
        if (o.getClass().getPackage().getName().startsWith("java.")) {
            return o.toString();
        }
    } catch (Exception ignored) {
    }
    return null;
}

public static JSONArray toJSONArray(Object array) throws JSONException {
    JSONArray result = new JSONArray();
    if (!array.getClass().isArray()) {
        throw new JSONException("Not a primitive array: " + array.getClass());
    }
    final int length = Array.getLength(array);
    for (int i = 0; i < length; ++i) {
        result.put(wrap(Array.get(array, i)));
    }
    return result;
}

【讨论】:

    【解决方案3】:

    这是一个 Gson 类型的适配器工厂,可以将 Bundle 转换为 JSON。

    https://github.com/google-gson/typeadapters/blob/master/android/src/main/java/BundleTypeAdapterFactory.java

    【讨论】:

      【解决方案4】:

      如果包有嵌套包,那么JSONObject.wrap(bundle.get(key)) 将返回null。所以我设法通过这个递归函数让它适用于我的用例。不过还没有测试过更高级的用例。

      JSONObject json = convertBundleToJson(bundle);
      
      public JSONObject convertBundleToJson(Bundle bundle) {
          JSONObject json = new JSONObject();
          Set<String> keys = bundle.keySet();
      
          for (String key : keys) {
              try {
                  if (bundle.get(key) != null && bundle.get(key).getClass().getName().equals("android.os.Bundle")) {
                      Bundle nestedBundle = (Bundle) bundle.get(key);
                      json.put(key, convertToJson(nestedBundle));
                  } else {
                      json.put(key, JSONObject.wrap(bundle.get(key)));
                  }
              } catch(JSONException e) {
                  System.out.println(e.toString());
              }
          }
      
          return json;
      }
      

      【讨论】:

        【解决方案5】:
        Object myJsonObj = bundleObject.get("yourKey");
        JsonParser parser = new JsonParser();
        JsonObject json = parser.parse(myJsonObj.toString()).getAsJsonObject();
        json.get("memberInJson").getAsString();
        

        【讨论】:

        • 我使用了 gson,因为 JSONObject.wrap 需要 Build 19。如果您有一个使用 gson 反序列化的预期对象。 :P
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-24
        • 1970-01-01
        • 1970-01-01
        • 2020-01-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多