Android JSONObject api16/api22 копия из HashMap отличается

Я получил странный JSONObject поведение на платформах api16 и api22 при преобразовании HashMap в 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"}

но когда этот код работает на Android 4.1, он производит это:

{"hashKey":"{key31=value31, key32=3200}","key2":2000,"key1":"value1"}

Почему это происходит и есть ли способ получить JSONObject правильно работает на всех 4+ телефонах?

1 ответ

Решение

Хорошо. Я исправил это. Перенос всего проекта в 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"}
Другие вопросы по тегам