1

I'm currently requesting an JsonObject via AsyncHttpClient (loopj) web request, however the request is rather slow and I need the Object to proceed. Currently the program crashes as the object being saved is empty and the save function gets called before the web request is complete.

Here's a snippet of my code of what i'm trying to do:

   btnCreate.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {


            AsyncHttpClient client = new AsyncHttpClient();
            String apiAddress = MYAPIADDRESS;

            client.get(apiAddress,
                    new JsonHttpResponseHandler() {

                        //@Override
                        public void onSuccess(int statusCode, Header[] headers, JSONObject response) {

                            try {

                                JSONObject tempTransition = response.getJSONArray("items").getJSONObject(0).getJSONObject("snippet");

                                Toast.makeText(getApplicationContext(), tempTransition.get("description").toString(), Toast.LENGTH_SHORT).show();

                                if(!dirDirectoryJson.contains(tempTransition)){
                                    dirDirectoryJson.add(tempTransition);
                                }

                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }

                        @Override
                        public void onSuccess(int statusCode, Header[] headers, JSONArray timeline) {

                        }

                        @Override
                        public void onFinish() {
                            // Completed the request (either success or failure)

                        }

                    });

                //*** Crashes here ****
                //dirDirectoryJson returning null object from above due to call before complete web request and crashes the program
                try {

                    getDescription = dirDirectoryJson.get(0).getString("description").toString().trim();
                    setDescription( getDescription ); 

               } catch (JSONException e) {
                    e.printStackTrace();
            }
     }

I've tried SyncHttpClient, make thread sleep etc. as well as seen/tried these (and many more other) links,

How to wait for async http to end before continuing?

https://forum.qt.io/topic/5389/how-to-ensure-fully-asynchronous-web-requests

How to wait for all requests to finish

How to make the Main thread wait, when i dont know when will Async task finish the job.?

I've also tried to toast the object received while commenting out the storing portion of the code. (commented above) The code didn't crash but the toast only appear after awhile when the web request is complete.

How do I go about resolving this issue? (i.e. successfully store the object without crashing the app only after the web request is complete). I've been searching very very long on the web but fail to get a workable method and i'm kinda a novice in Android.

Do kindly help and let me know if more details is required. Thanks in advance!

Community
  • 1
  • 1
Candiie
  • 23
  • 5
  • which is the save function ? – Shubhank May 14 '16 at 05:44
  • @Shubhank Hi! I've commented in the code above actually, in the last try catch. it crashes at the storing before even reaching the save :'( i've done the edit, sry for the typo. – Candiie May 14 '16 at 06:54
  • please move that code in the on success as well – Shubhank May 14 '16 at 06:55
  • @Shubhank Hi, I've tried, it says my variables, getDescription & setDescription have to be declared final but I can't declare them as final. – Candiie May 14 '16 at 06:58
  • declare them as instance var then @Candiie – Shubhank May 14 '16 at 07:03
  • @Shubhank omgosh! Thank you so so much!!! That was so silly of me! Can't believe i took so many hours trying to get this working!!! ><" Thank you so so much! How do i set your reply as the correct answer ? since you posted it as a comment. – Candiie May 14 '16 at 08:05
  • no problem. i will post as a answer :) – Shubhank May 14 '16 at 08:07

2 Answers2

0

Since async calls run in background , your remaining code executes before the data is saved actually.

getDescription=dirDirectoryJson.get(0).getString("description").toString().trim();
                setDescription( getDescription );

write these lines into your onSuccess method to make it work.

Pro Mode
  • 1,453
  • 17
  • 30
  • Hi, I've tried, it says my variables, getDescription & setDescription have to be declared final but I can't declare them as final as i have to edit the data. – Candiie May 14 '16 at 07:01
  • then put this code in another custom method and call that method in onSuccess method. – Pro Mode May 14 '16 at 07:17
  • Hi I got it working already! From @shubhank's reply, I think your method would work too but since he replied first I'll have to set his as the ans. Nonetheless thank you so much! – Candiie May 14 '16 at 08:08
0

Since the request you are doing is async, you should do the logic of using the response of the request in its completion handler.

Change your code to something like

public void onSuccess(int statusCode, Header[] headers, JSONObject response) {

 try {

     JSONObject tempTransition = response.getJSONArray("items").getJSONObject(0).getJSONObject("snippet");

     Toast.makeText(getApplicationContext(), tempTransition.get("description").toString(), Toast.LENGTH_SHORT).show();

     if(!dirDirectoryJson.contains(tempTransition)){
           dirDirectoryJson.add(tempTransition);
     }

     getDescription = dirDirectoryJson.get(0).getString("description").toString().trim();
                setDescription( getDescription );
   } catch (JSONException e) {
      e.printStackTrace();
   }
}

Also make your variables as instance var (that is declare them at class scope) if shows cant access non final variables within the handler

Shubhank
  • 21,721
  • 8
  • 65
  • 83