Search code examples
androidparse-platformandroid-asynctask

Android display gets rendered before getting values from backend


I am a bit new to android and trying to develop my own app using parse as backend. Here I am trying to get the number of comments for a post from parse. When I do the call back using an asynctask the data in the UI gets rendered even before data returns showing all my comments as zero even when they are not. When I debug I get the correct size but its being displayed even before that. When I tried to debug using the logs as shown in code below this is how I got the debug.

2020-04-21 13:53:58.984 22308-22589/com.project I/gg: outside
2020-04-21 13:53:59.090 22308-22595/com.project I/gg: outside
2020-04-21 13:53:59.127 22308-22598/com.project I/gg: outside
2020-04-21 13:53:59.162 22308-22601/com.project I/gg: outside
2020-04-21 13:53:59.203 22308-22589/com.project I/gg: outside
2020-04-21 13:53:59.238 22308-22595/com.project I/gg: outside
2020-04-21 13:53:59.247 22308-22308/com.project I/gg: post
2020-04-21 13:53:59.470 22308-22308/com.project I/gg: post
2020-04-21 13:53:59.472 22308-22308/com.project I/gg: post
2020-04-21 13:53:59.523 22308-22308/com.project I/gg: inside
2020-04-21 13:53:59.843 22308-22308/com.project I/gg: inside
2020-04-21 13:54:00.156 22308-22308/com.project I/gg: inside
2020-04-21 13:54:00.176 22308-22308/com.project I/gg: inside
2020-04-21 13:54:00.325 22308-22308/com.project I/gg: inside

As you can see the process is not happening in the right order.

Will be glad if someone could point out the error. If any other resource is needed to answer this question feel free to ask I will add it. Thank you.

 static public class CommentAsyncTask extends AsyncTask<Void, String, String> {
            String objectId;
            TextView commentsView;

        CommentAsyncTask(String objectId, TextView commentsView) {
            this.objectId = objectId;
            this.commentsView = commentsView;
        }
        @Override
        protected String doInBackground(Void... voids) {
            ParseQuery<ParseObject> objectParseQuery = ParseQuery.getQuery("Comments");
            objectParseQuery.whereEqualTo("quoteId", objectId);
            objectParseQuery.setLimit(20);
            objectParseQuery.orderByAscending("createdAt");
            final Bitmap[] tempBitmap = new Bitmap[1];
            final int[] size = new int[1];
            Log.i("gg", "outside");
            objectParseQuery.findInBackground(new FindCallback<ParseObject>() {
                @Override
                public void done(List<ParseObject> objects, ParseException e) {
                    if (e == null) {
                        size[0] = objects.size();
                        Log.i("gg", "inside");
                    }
                }
            });
            return String.valueOf(size[0]);
        }


        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            if(s != null){
                commentsView.setText("View all " + s + " comments");
            }
            Log.i("gg","post");
        }
    }

Solution

  • In doInBackground method you are setting a listener and then going to postExecute without waiting for result so you get zero. if there is any sync version for the method you are using, then you should use that instead of callback version inside AsyncTask or you can forget about AsyncTask and call findInBackground from UI thread like this:

     // here you set call back without waiting for result
    //so it could be used from UI thread instead of AsyncTask
    objectParseQuery.findInBackground(new FindCallback<ParseObject>() { 
            @Override
            public void done(List<ParseObject> objects, ParseException e) {
                if (e == null) {
                    Log.i("gg", "inside");
                    commentsView.setText("View all " + objects.size() + " comments");// set text here
                }
            }
    });