sagar suri
sagar suri

Reputation: 4741

Weird issue while parsing JSONObjects and converting to Java objects

This is the first time I am facing a very weird problem. I have a JSONObject mentioned below.:

Link for the JSON body (Cant paste JSON body here because of character limit): http://kolam.vicz.in:7890/games_gifs/

I am parsing the above set of JSONObjects and converting them to Java objects. Below is my code of parsing this JSON body.

private void getGameList() {
        StringRequest request = new StringRequest(Request.Method.GET, gameUrl, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                try {
                    JSONObject mainObject = new JSONObject(response);
                    JSONArray gamesArray = mainObject.getJSONArray("TracingGames");
                    Log.e(TAG, "gameArray length:" + gamesArray.length());
                    for (int i = 0; i < gamesArray.length(); i++) {
                        JSONObject obj = gamesArray.getJSONObject(i);
                        for (String str : getKeys(obj)) {
                            Log.e(TAG, str);
                            if (str.equalsIgnoreCase("kolam")) {

                                /*Section for Learn and Kolam Tracing games start*/
                                //TODO: Need to add the game names to the object (Need server side implementation as well)
                                KolamTracingGames kolamTracingGames = new KolamTracingGames();
                                kolamTracingGames.setKolamGifPath(obj.getString("path"));
                                kolamTracingGames.setKolamLevel(Integer.parseInt(str));
                                kolamTracingGames.setKolamGameName("Kolam Tracing");
                                kolamTracingGames.setX(getXCoordinates(obj));
                                kolamTracingGames.setY(getYCoordinates(obj));
                                kolamObjects.add(kolamTracingGames);
                                break;
                            } else if (str.equalsIgnoreCase("level")) {
                                LearnTracingGames learnTracingGames = new LearnTracingGames();
                                learnTracingGames.setLearnGameGifPath(obj.getString("path"));
                                learnTracingGames.setLearnGameLevel(Integer.parseInt(str));
                                learnTracingGames.setGameName("Learn Game");
                                learnTracingGames.setX(getXCoordinates(obj));
                                learnTracingGames.setY(getYCoordinates(obj));
                                learnGameObjects.add(learnTracingGames);
                                Log.e(TAG, learnGameObjects.size() + "");
                                break;
                            }
                        }
                    }

                    if (gameType.equalsIgnoreCase("Trace the Kolam")) {
                        kolamTraceAdapter = new KolamTraceAdapter(getActivity());
                        kolamTraceAdapter.getGameList(kolamObjects);
                        recyclerView.setAdapter(kolamTraceAdapter);
                    } else if (gameType.equalsIgnoreCase("Learn")) {
                        learnGameAdapter = new LearningGameAdapter(getActivity());
                        learnGameAdapter.getGameList(learnGameObjects);
                        Log.e(TAG, "learngameobject size:" + learnGameObjects.size());
                        recyclerView.setAdapter(learnGameAdapter);
                        Log.e(TAG, "Learn games");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, error.getMessage());
                if (getActivity() != null) {
                    Alerter.create(getActivity())
                            .setTitle(R.string.warning)
                            .setText(R.string.network_error)
                            .setDuration(2000)
                            .setBackgroundColorRes(R.color.dot_dark_screen1)
                            .show();
                }
            }
        });
        request.setTag(TAG);
        request.setRetryPolicy(new DefaultRetryPolicy(30000, 5, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        AppController.getInstance().addToRequestQueue(request);

My problem is there are 8 level type objects and 4 kolam objects (Please refer the JSON body for clarity). I am having two separate POJO classes for them. I am able to parse the JSON body properly but when I am trying to create Java objects of those JSONObjects the inner most for loop is not running completely. Its stopping after 1 loop.

the inner for loop is not getting executed completely (executing only once but should get executed more then 12 times) if I am doing this (Creating Java Objects):

for (int i = 0; i < gamesArray.length(); i++) {
                        JSONObject obj = gamesArray.getJSONObject(i);
                        for (String str : getKeys(obj)) {
                            Log.e(TAG, str);
                            if (str.equalsIgnoreCase("kolam")) {

                                /*Section for Learn and Kolam Tracing games start*/
                                //TODO: Need to add the game names to the object (Need server side implementation as well)
                                KolamTracingGames kolamTracingGames = new KolamTracingGames();
                                kolamTracingGames.setKolamGifPath(obj.getString("path"));
                                kolamTracingGames.setKolamLevel(Integer.parseInt(str));
                                kolamTracingGames.setKolamGameName("Kolam Tracing");
                                kolamTracingGames.setX(getXCoordinates(obj));
                                kolamTracingGames.setY(getYCoordinates(obj));
                                kolamObjects.add(kolamTracingGames);
                                break;
                            } else if (str.equalsIgnoreCase("level")) {
                                LearnTracingGames learnTracingGames = new LearnTracingGames();
                                learnTracingGames.setLearnGameGifPath(obj.getString("path"));
                                learnTracingGames.setLearnGameLevel(Integer.parseInt(str));
                                learnTracingGames.setGameName("Learn Game");
                                learnTracingGames.setX(getXCoordinates(obj));
                                learnTracingGames.setY(getYCoordinates(obj));
                                learnGameObjects.add(learnTracingGames);
                                Log.e(TAG, learnGameObjects.size() + "");
                                break;
                            }
                        }
                    }

the getKeys(JSONObject) method is below:

private static String[] getKeys(JSONObject firstJSONObject) {
        Iterator keysToCopyIterator = firstJSONObject.keys();
        List<String> keysList = new ArrayList<>();
        while (keysToCopyIterator.hasNext()) {
            String key = (String) keysToCopyIterator.next();
            keysList.add(key);
        }
        return keysList.toArray(new String[keysList.size()]);
    }

But If I avoid creating objects inside the for loop then the inner for loop runs completely.

Upvotes: 3

Views: 65

Answers (1)

Pavneet_Singh
Pavneet_Singh

Reputation: 37414

But If I avoid creating objects inside the for loop then the inner for loop runs completely.

Integer.parseInt("level") or Integer.parseInt("kolam") which is clearly a crash

Explanation

when your any of if (str.equalsIgnoreCase("kolam")) or else if (str.equalsIgnoreCase("level")) { matches then

you clearly have a crash here , Integer.parseInt(str) because str will either be level or kolam which are clearly not integers

Solution : Don't use str instead fetch the values

if (str.equalsIgnoreCase("kolam")) {
    //... code
    kolamTracingGames.setKolamLevel(obj.optInt(str));
    //... code                      ^^^^^^^^^^^^^^^
    break;
} else if (str.equalsIgnoreCase("level")) {
    //... code
    learnTracingGames.setLearnGameLevel(obj.optInt(str));
    //... code                          ^^^^^^^^^^^^^^^
    break;
}

Upvotes: 2

Related Questions