10

I use the following code for converting Json string(strWebserviceResult) to my Object:

EntMyClass entMyClass = gson.fromJson(strWebserviceResult,EntMyClass.class);

When strWebserviceResult is large (about 2.5 MB) I get the Out of memory exception on this line on Android phone devices not in Tablet that has larger memory.

How can I solve that.

Does anybody have any suggestion?

05-26 15:52:49.607: E/dalvikvm-heap(2078): Out of memory on a 9200-byte allocation.
05-26 15:52:49.618: E/dalvikvm(2078): Out of memory: Heap Size=31879KB, Allocated=27693KB, Bitmap Size=936KB, Limit=32768KB
05-26 15:52:49.618: E/dalvikvm(2078): Extra info: Footprint=31879KB, Allowed Footprint=31879KB, Trimmed=7400KB
05-26 15:52:49.618: E/AndroidRuntime(2078): FATAL EXCEPTION: Thread-19
05-26 15:52:49.618: E/AndroidRuntime(2078): java.lang.OutOfMemoryError: (Heap Size=31879KB, Allocated=27693KB, Bitmap Size=936KB)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at java.util.ArrayList.add(ArrayList.java:123)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter.deserialize(DefaultTypeAdapters.java:664)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter.deserialize(DefaultTypeAdapters.java:624)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at com.google.gson.JsonDeserializerExceptionWrapper.deserialize(JsonDeserializerExceptionWrapper.java:51)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at com.google.gson.JsonDeserializationVisitor.invokeCustomDeserializer(JsonDeserializationVisitor.java:92)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at com.google.gson.JsonObjectDeserializationVisitor.visitFieldUsingCustomHandler(JsonObjectDeserializationVisitor.java:117)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at com.google.gson.ReflectingFieldNavigator.visitFieldsReflectively(ReflectingFieldNavigator.java:63)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:120)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at com.google.gson.JsonDeserializationContextDefault.fromJsonObject(JsonDeserializationContextDefault.java:76)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at com.google.gson.JsonDeserializationContextDefault.deserialize(JsonDeserializationContextDefault.java:54)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter.deserialize(DefaultTypeAdapters.java:663)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter.deserialize(DefaultTypeAdapters.java:624)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at com.google.gson.JsonDeserializerExceptionWrapper.deserialize(JsonDeserializerExceptionWrapper.java:51)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at com.google.gson.JsonDeserializationVisitor.invokeCustomDeserializer(JsonDeserializationVisitor.java:92)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at com.google.gson.JsonDeserializationVisitor.visitUsingCustomHandler(JsonDeserializationVisitor.java:80)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:101)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at com.google.gson.JsonDeserializationContextDefault.fromJsonArray(JsonDeserializationContextDefault.java:67)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at com.google.gson.JsonDeserializationContextDefault.deserialize(JsonDeserializationContextDefault.java:52)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at com.google.gson.Gson.fromJson(Gson.java:551)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at com.google.gson.Gson.fromJson(Gson.java:498)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at com.google.gson.Gson.fromJson(Gson.java:467)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at com.google.gson.Gson.fromJson(Gson.java:417)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at com.google.gson.Gson.fromJson(Gson.java:389)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at org.mabna.order.businessLayer.BoWebService.getDataForUpdate(BoWebService.java:188)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at org.mabna.order.ui.ActToolDataExchange.threadGetDataForFullUpdate(ActToolDataExchange.java:371)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at org.mabna.order.ui.ActToolDataExchange.access$9(ActToolDataExchange.java:362)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at org.mabna.order.ui.ActToolDataExchange$33.run(ActToolDataExchange.java:603)
05-26 15:52:49.618: E/AndroidRuntime(2078):     at org.mabna.order.utils.Utilities$5.run(Utilities.java:778)
4

4 回答 4

6

尝试使用将JsonReader 作为输入的fromJson方法。这应该允许您一次不需要整个输入字符串都在内存中。这是一些示例代码:

        final HttpURLConnection c = (HttpURLConnection) url.openConnection();
        final InputStreamReader isr = new InputStreamReader(c.getInputStream());
        final JsonReader reader = new JsonReader(isr);
        final EntMyClass entMyClass = GSON.fromJson(reader, EntMyClass.class);
        reader.close();
        c.disconnect();
于 2012-06-11T15:47:49.857 回答
6

与另一篇文章一样,我会问是否有任何方法可以避免您的应用程序使用大量内存。如果你能做到这一点,那将是最优化的解决方案。如果您的应用确实需要这么多内存,您可以尝试android:largeHeap="true"在清单中为您的应用设置。这是参考:

http://developer.android.com/reference/android/R.styleable.html#AndroidManifestApplication_largeHeap

有关更多信息,请参阅此视频:

http://www.youtube.com/watch?v=_CruQY55HOk

于 2012-06-11T16:57:36.883 回答
3

首先。您真的需要将 2.5MB 数据加载到内存中吗?
首先创建了一个大字符串,然后对其进行解析(内存中的另一个对象),然后创建了一个巨大的 EntMyClass 实例。这种方法确实效率低下。

我猜你在这个对象中有 List 。只有您提供的信息,我建议将数据流式传输到数据库中。然后您可以创建适配器以在 ListView 中显示数据。

有很多方法可以做到这一点。我正在使用 Jackson 库,因为它是最快的,GSON 应该具有类似的功能。

假设您在此对象中有一个列表,下面是如何将 json 数组存储在数据库中的示例:

    //create parser
    final JsonParser jsonParser = objectMapper.getJsonFactory().createJsonParser(inputStream);

    JsonToken jsonToken = jsonParser.nextToken();
    while ((jsonToken = jsonParser.nextToken()) != null && jsonToken != JsonToken.END_ARRAY) {
        //map json object to ItemClass
        final ItemClass item = jsonParser.readValueAs(ItemClass.class);
        //store in database
        itemDAO.insert(item);
    }

并用数据库事务围绕它,不仅数据会在出错的情况下回滚,而且效率更高。

于 2012-06-11T16:01:54.690 回答
0

请阅读 gson 作者的答案 -这里

还有我的 5 美分:

        JsonReader r = null;
        try {
            Reader reader = new BufferedReader(new InputStreamReader(is));
            r = new JsonReader(reader);
            result = gson.fromJson(r, clazz);
        } finally {
            if (null != r) {
                r.close();
            }
        }
于 2012-06-16T19:25:41.527 回答