2014-12-13 2 views
1

Я пытаюсь декодировать строку json и делать что-то с содержимым. У меня есть этот код, который выполняется всякий раз, когда пользователь нажимает на кнопку:Java Android Json OutOfMemoryError

public List<Card> readCards() 
{ 
    List<Card> cards = new ArrayList<Card>(); 

    HttpReader httpReader = new HttpReader(); 
    httpReader.setOnResultReadyListener(new HttpReader.OnResultReadyListener() { 
     @Override 
     public void resultReady(String result) { 
      JsonHelper jsonHelper = new JsonHelper(); 
      List<Card> cards = jsonHelper.getCards(result); 

      for (int i = 0; i < cards.size(); i++) { 
       cards.add(new Card(cards.get(i).getId(), cards.get(i).getNaam(), cards.get(i).getMana(), cards.get(i).getAttack(), cards.get(i).getHealth(), cards.get(i).getEffect(), cards.get(i).getZeldzaamheid(), cards.get(i).getTypeId(), cards.get(i).getSubtypeId(), cards.get(i).getClassId(), cards.get(i).isGoud())); 
      } 
     } 
    }); 
    httpReader.execute("http://jsonstring.com"); //link to json-file 

    return cards; 
} 

getCards(result) метод из jsonHelper класса заключается в следующем:

public List<Card> getCards(String jsonText) { 
    List<Card> list= new ArrayList<Card>(); 

    try { 
     JSONArray jsonArrayCards = new JSONArray(jsonText); 
     for (int i = 0; i < jsonArrayCards.length(); i++) { 
      JSONObject jsonObjectCard = jsonArrayCards.getJSONObject(i);  

       Card card = new Card(); 
       if (jsonObjectCard.has("id")) { card.setId(jsonObjectCard.getString("id")); } else { card.setId("none"); } 
       if (jsonObjectCard.has("name")) { card.setNaam(jsonObjectCard.getString("name")); } else { card.setNaam("none"); } 
       if (jsonObjectCard.has("cost")) { card.setMana(jsonObjectCard.getInt("cost")); } else { card.setMana(0); } 
       if (jsonObjectCard.has("attack")) { card.setAttack(jsonObjectCard.getInt("attack")); } else { card.setAttack(0); } 
       if (jsonObjectCard.has("health")) { card.setHealth(jsonObjectCard.getInt("health")); } else { card.setHealth(0); } 
       if (jsonObjectCard.has("text")) { card.setEffect(jsonObjectCard.getString("text")); } else { card.setEffect(""); } 
       card.setTypeId(1); 
       card.setSubtypeId(1); 
       card.setClassId(1); 
       list.add(card); 
     } 
    } catch (JSONException e) { 
     Log.e("JSON Parser", "Error parsing data " + e.toString()); 
    } 

    return list; 
} 

После того, как это делается, я пытаюсь показать размер из возвращаемого списка, который по какой-то причине равен 0.

После нажатия кнопки в первый раз приложение замерзает. Журнал показывает a java.lang.OutOfMemoryError

Файл json - < 200 строк, которые могут быть 5kb, поэтому это не должно быть проблемой.

Любая помощь будет высоко оценена.

+0

Действительно ли ваша ссылка json что-то возвращает? Я пробовал http://jsonstring.com и ничего не получил, или я чего-то не хватает? –

+0

в моем фактическом коде. У меня есть ссылка на мое личное веб-пространство, которое я здесь забыл. Я получаю что-то обратно от фактической ссылки json. – Droes

+1

Выглядит мне, используя этот цикл FOR, вы снова добавляете записи. Это то, что вы на самом деле предназначили. – Shiv

ответ

5

Ваша программа застряла в бесконечном цикле. Вы добавляете карты в списке карт, который продолжает расти, пока вы не получите из памяти

 for (int i = 0; i < cards.size(); i++) { 
      cards.add(new Card(cards.get(i).getId(),... 
     } 

Loop никогда не может закончить, потому что вы проверить, что i < cards.size() и с каждым new Card добавил cards.size увеличивается.

+0

Вот и все. Не могу поверить, что я этого не видел. Спасибо за ответ! – Droes

2

Ваш цикл является причиной ошибки

 for (int i = 0; i < cards.size(); i++) 

и с помощью cards.size() в цикл не лучшая практика. Вместо этого используйте

 int count = cards.size(); 

Всегда используйте этот цикл int in for. Это быстрее, чем у старого. Потому что в старом коде каждый раз ваш счетчик для подсчета очков