Android JSONObject api16/api22 来自 HashMap 的副本不同
Android JSONObject api16/api22 copy from HashMap differs
将 HashMap 转换为 JSONObject
时,我在 api16 和 api22 平台上遇到了一个奇怪的 JSONObject
行为。所以这是测试代码:
HashMap<String, Object> hash1 = new HashMap<String, Object>() {{
put("key1", "value1");
put("key2", 2000);
}};
HashMap<String, Object> hash2 = new HashMap<String, Object>() {{
put("key31", "value31");
put("key32", 3200);
}};
hash1.put("hashKey", hash2);
JSONObject json = new JSONObject(hash1);
String jsonString = json.toString();
如果我 运行 android 5.1 上的这段代码我得到了这个字符串(它很好而且正确):
{"key2":2000,"hashKey":{"key31":"value31","key32":3200},"key1":"value1"}
但是当这段代码 运行ning 在 Android 4.1 上时它会产生这个:
{"hashKey":"{key31=value31, key32=3200}","key2":2000,"key1":"value1"}
为什么会发生这种情况,有什么方法可以让 JSONObject
在所有 4+ 手机上正常工作?
好的。我修好了这个。把整个项目迁移到gson太贵了,所以我借用了一些从来没有的JSONObject版本的代码,做了一个静态复制的方法。
这是一个静态方法:
public class JSONCopy extends JSONObject {
public static JSONObject hashMap2JSONObject(Map copyFrom) throws JSONException {
JSONObject newJson = new JSONObject();
Map<?, ?> contentsTyped = (Map<?, ?>) copyFrom;
for (Map.Entry<?, ?> entry : contentsTyped.entrySet()) {
String key = (String) entry.getKey();
if (key == null) {
throw new NullPointerException("key == null");
}
newJson.put(key, wrap(entry.getValue()));
}
return newJson;
}
public static Object getJSONArray(Object o) throws JSONException {
JSONArray newValue = new JSONArray();
if (!o.getClass().isArray()) {
throw new JSONException("Not a primitive array: " + o.getClass());
}
final int length = Array.getLength(o);
for (int i = 0; i < length; ++i) {
newValue.put(wrap(Array.get(o, i)));
}
return newValue;
}
public static Object wrap(Object o) {
if (o == null) {
return NULL;
}
if (o instanceof JSONArray || o instanceof JSONObject) {
return o;
}
if (o.equals(NULL)) {
return o;
}
try {
if (o instanceof Collection) {
return new JSONArray((Collection) o);
} else if (o.getClass().isArray()) {
return getJSONArray(o);
}
if (o instanceof Map) {
return hashMap2JSONObject((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 void testCopy() {
HashMap<String, Object> hash1 = new HashMap<String, Object>() {{
put("key1", "value1");
put("key2", 2000);
}};
HashMap<String, Object> hash2 = new HashMap<String, Object>() {{
put("key31", "value31");
put("key32", 3200);
}};
HashMap<String, Object> hash3 = new HashMap<String, Object>() {{
put("key41", "value41");
put("key42", 4200);
put("key43", true);
}};
HashMap<String, Object> hash4 = new HashMap<String, Object>() {{
put("key51", "value51");
put("key52", 5200);
put("key53", true);
}};
hash3.put("hashKey4", hash4);
hash2.put("hashKey3", hash3);
hash1.put("hashKey2", hash2);
try {
JSONObject json = hashMap2JSONObject(hash1);
String jsonString = json.toString();
Log.d("testCopy()", jsonString);
} catch (Exception e) {
e.printStackTrace();
}
}
这是结果(在 4.0、4.1、4.2、5.1 上测试):
D/testCopy(): {"hashKey2":{"key31":"value31","key32":3200,
"hashKey3":{"key42":4200,"key41":"value41","key43":true,
"hashKey4":{"key51":"value51","key53":true,"key52":5200}}},
"key2":2000,"key1":"value1"}
将 HashMap 转换为 JSONObject
时,我在 api16 和 api22 平台上遇到了一个奇怪的 JSONObject
行为。所以这是测试代码:
HashMap<String, Object> hash1 = new HashMap<String, Object>() {{
put("key1", "value1");
put("key2", 2000);
}};
HashMap<String, Object> hash2 = new HashMap<String, Object>() {{
put("key31", "value31");
put("key32", 3200);
}};
hash1.put("hashKey", hash2);
JSONObject json = new JSONObject(hash1);
String jsonString = json.toString();
如果我 运行 android 5.1 上的这段代码我得到了这个字符串(它很好而且正确):
{"key2":2000,"hashKey":{"key31":"value31","key32":3200},"key1":"value1"}
但是当这段代码 运行ning 在 Android 4.1 上时它会产生这个:
{"hashKey":"{key31=value31, key32=3200}","key2":2000,"key1":"value1"}
为什么会发生这种情况,有什么方法可以让 JSONObject
在所有 4+ 手机上正常工作?
好的。我修好了这个。把整个项目迁移到gson太贵了,所以我借用了一些从来没有的JSONObject版本的代码,做了一个静态复制的方法。
这是一个静态方法:
public class JSONCopy extends JSONObject {
public static JSONObject hashMap2JSONObject(Map copyFrom) throws JSONException {
JSONObject newJson = new JSONObject();
Map<?, ?> contentsTyped = (Map<?, ?>) copyFrom;
for (Map.Entry<?, ?> entry : contentsTyped.entrySet()) {
String key = (String) entry.getKey();
if (key == null) {
throw new NullPointerException("key == null");
}
newJson.put(key, wrap(entry.getValue()));
}
return newJson;
}
public static Object getJSONArray(Object o) throws JSONException {
JSONArray newValue = new JSONArray();
if (!o.getClass().isArray()) {
throw new JSONException("Not a primitive array: " + o.getClass());
}
final int length = Array.getLength(o);
for (int i = 0; i < length; ++i) {
newValue.put(wrap(Array.get(o, i)));
}
return newValue;
}
public static Object wrap(Object o) {
if (o == null) {
return NULL;
}
if (o instanceof JSONArray || o instanceof JSONObject) {
return o;
}
if (o.equals(NULL)) {
return o;
}
try {
if (o instanceof Collection) {
return new JSONArray((Collection) o);
} else if (o.getClass().isArray()) {
return getJSONArray(o);
}
if (o instanceof Map) {
return hashMap2JSONObject((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 void testCopy() {
HashMap<String, Object> hash1 = new HashMap<String, Object>() {{
put("key1", "value1");
put("key2", 2000);
}};
HashMap<String, Object> hash2 = new HashMap<String, Object>() {{
put("key31", "value31");
put("key32", 3200);
}};
HashMap<String, Object> hash3 = new HashMap<String, Object>() {{
put("key41", "value41");
put("key42", 4200);
put("key43", true);
}};
HashMap<String, Object> hash4 = new HashMap<String, Object>() {{
put("key51", "value51");
put("key52", 5200);
put("key53", true);
}};
hash3.put("hashKey4", hash4);
hash2.put("hashKey3", hash3);
hash1.put("hashKey2", hash2);
try {
JSONObject json = hashMap2JSONObject(hash1);
String jsonString = json.toString();
Log.d("testCopy()", jsonString);
} catch (Exception e) {
e.printStackTrace();
}
}
这是结果(在 4.0、4.1、4.2、5.1 上测试):
D/testCopy(): {"hashKey2":{"key31":"value31","key32":3200,
"hashKey3":{"key42":4200,"key41":"value41","key43":true,
"hashKey4":{"key51":"value51","key53":true,"key52":5200}}},
"key2":2000,"key1":"value1"}