3

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.

4
  • Just out of curiosity...why are you trying to parse the JSON yourself? Seeing that you are on Android, have you considered using eg. Gson? Cause then it could in theory be as easy as writing KolamTracingGmaes games = new Gson().fromJson(response, KolamTracingGames.class) Commented Aug 23, 2017 at 16:49
  • I thought you have break statement Commented Aug 23, 2017 at 16:51
  • I have tried every possible way.. I can parse the JSON body easily and completely if I am not creating those Java objects. Just commenting those objects setter method lines make the code run successfully. But if I run the above code. Then it's running only for 1 time Commented Aug 23, 2017 at 16:54
  • break statement is not the problem here. @Yohannes Commented Aug 23, 2017 at 16:56

1 Answer 1

2

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;
}
Sign up to request clarification or add additional context in comments.

5 Comments

Great solution. I just came out of my home..will update once that runs successfully..amazing man. Thanks a ton
@Hiren i am glad that i could help , happy coding
I just wanted to know. Why didn't the java compiler throw any error or exception regarding that ?
@Hiren because you applied the try-catch and you used Exception which will handle every exception but still the exception details is available to you in logcat via e.printStackTrace(); although to bring a crash just add catch blocks for necessary parsing exceptions like JSONException
it's always good practice to catch the expected exceptions for quick debugging instead of Exception, use replace catch (Exception e) { with catch (JSONException e) { to view NumberFormatException

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.