JSONObject.toString () возвращает OutOfMemoryError

1

У меня есть приложение для Android. Во-первых, приложение выполняет синхронизацию. В этом процессе сервер отправляет на устройство объект JSON как String, с помощью которого он может создавать доступные опросные листы.

GetQuestionnairesResponse.java:

public class GetQuestionnairesResponse extends ResponseHandler
{

public GetQuestionnairesResponse(String result, AsyncRequest request)
{
    super(result, request);
}

@Override
public void handleResponse()
{
    DataSyncActivity caller = (DataSyncActivity) request.getCaller();
    BackgroundManager bckMng = BackgroundManager.getInstance(caller);
    PreferencesManager preference = PreferencesManager.getInstance(null);

    boolean status = true;
    int numOfWrongJsonVer = 0;
    int totalNumOfQuestionnaires = 0;
    // Handle data from server

    // Creating JSON Parser instance
    try
    {
        QuestionnaireDataSource questionnaireDS = new QuestionnaireDataSource(caller);
        questionnaireDS.open();
        JSONArray jArr = new JSONArray(result);
        JSONObject j = null;
        totalNumOfQuestionnaires = jArr.length();
        for (int i = 0; i < jArr.length(); i++)
        {
            j = jArr.getJSONObject(i);
            long questId = j.getLong("questionnaireId");
            long surveyId = j.getLong("surveyId");
            String questName = j.getString("name");
            String desc = j.getString("description");
            int version = j.getInt("questionnaireVersion");
            int jsonVersion = j.getInt("jsonVersion");

            if (jsonVersion == PreferencesManager.jsonVersion)
            {
                // Save the pages part
                String filename = questId + "_" + version + "_" + jsonVersion + ".json";
                HelpFunctions.writeJSON(filename, j.toString());

                Questionnaire quest = questionnaireDS.createQuestionnaire(questId, questName, desc, surveyId, version, jsonVersion, filename);

                if (quest == null)
                    throw new RuntimeException("Cant save the questionnaire: " + questName);
            }
            else
            {
                numOfWrongJsonVer ++;
            }
        }
        questionnaireDS.close();
    }
    catch (Exception e)
    {
        status = false;
        if (e.getMessage() != null)
            Log.e(TAG, e.getMessage());
    }

    caller.setInSync(false);


    ...
}

Результат, который я получаю от сервера, анализирую его на массив Json. Результат в некоторых случаях может составлять 3 мегабайта.

Решение, которое я нашел, это добавить атрибут в manifest.xml:

   android:largeHeap="true"

Он решил проблему. Я не знаю, почему, но проблема снова вернулась в последний день. Я буду рад получить предложения по решению проблемы. Проблема в том, что объект json не анализировался так, как ожидалось, поэтому он

  • 0
    вместо того , чтобы конвертировать Json объекта самовывозом использовать библиотеку третьей стороны , как Gson и Jakson . не используйте largHeap для этой проблемы. если вы хотите конвертировать самостоятельно, вы копируете все json в память, и, поскольку ваш json очень большой (я думаю), вы получаете ошибку OOM
  • 0
    Можете ли вы показать на небольшом примере, что вы имеете в виду, пожалуйста?
Показать ещё 1 комментарий
Теги:

1 ответ

2

Если JSON был изначально 3 МБ, и вы вызывали toString() на JSONObject, который был проанализирован из него, JSONObject по-прежнему занимает память, плюс ему потребуется сделать выделение 3 МБ для хранения String. Возможно, у вас не так много доступной памяти.

Но дело в OutOfMemoryError заключается в том, что распределение, использующее последний бит ОЗУ, не обязательно виноват в том, что имеется так мало доступной ОЗУ. Большие ассигнования, скорее всего, будут тем, что подталкивает его к краю. Вероятно, у вас есть утечка памяти где-то еще в вашем приложении, и вам нужно использовать инструмент, например Eclipse MAT, чтобы найти его.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню