Droes
Droes

Reputation: 75

Java Android Json OutOfMemoryError

I'm trying to decode a json string and do something with the contents. I have this code that runs whenever the user presses a button:

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;
}

The getCards(result) method from the jsonHelper class is this:

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;
}

After this is done I'm trying to show to the size of the returned list, which is 0 for some reason.

After clicking the button the first time the app freezes. Log shows a java.lang.OutOfMemoryError

The json file is <200 lines which is maybe 5kb so that should not be a problem.

Any help would be much appreciated.

Upvotes: 1

Views: 101

Answers (2)

Indra Kumar S
Indra Kumar S

Reputation: 2934

Your for loop is the cause of the error

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

And Using cards.size() in for loop is not a best practice. Instead use

     int count = cards.size();

Always use this int in for loop. This is more faster than the older one. Because In old code, every time your for loop counts for cards

Upvotes: 2

Dalija Prasnikar
Dalija Prasnikar

Reputation: 28517

Your program is stuck in infinite loop. You are adding cards to your cards list that keeps growing until you get out of memory

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

Loop can never finish because you test that i < cards.size() and with each new Card added cards.size increases.

Upvotes: 5

Related Questions