-1

In a fragment I'm using an 'AsyncTask' to retrieve data from a URL. The main purpose of my code is to access the data (via AsyncTask) and to pass a 'JSONArray' to the fragment. Problem is, on the fragment side, that when I check the variable that should have the result i get an error saying that the variable is null.

Here is the code:

    public class MyFragment extends ListFragment {
        //this is the variable that should have the result from the AsyncTask
        JSONArray myResult = null;

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            (...)
            //execute the asyncTask
            new GetResult().execute(email, password);
            (...)
        }

        //The AsyncTask
        private class GetResult extends AsyncTask<String, Void, JSONArray> {
            @Override
            protected JSONArray doInBackground(String... params) {

                (...)

                JSONArray jsonArray = (JSONArray) json.get("customer");
                return jsonArray;
            }

            protected void onPostExecute(JSONArray result){
                (...)
                //this is where I try to pass the data to the fragment
                MyFragment.this.myResult = result;
            }

        }


    }

Can someone can help me with that? Thank you in advance.

BlueHatCoder
  • 87
  • 1
  • 2
  • 7

5 Answers5

0

Are you using the value after postExecute method. You should know that after calling execute, your code on the main thread still runs and only after postExecute has completed, will you have the value.

Ramandeep Nanda
  • 519
  • 3
  • 9
  • I put a Toast message in 'onPostExecute' just to check if 'myResult' was returning any value than 'null' and turns out that I get the value I wanted (which is not 'null'). But like you said, I'm trying to read the variable before the AsyncTask finishes...if so, how do I solve this problem? I mean, how do I get the value after the AsyncTask finishes? – BlueHatCoder Jun 02 '15 at 21:23
  • Well whatever you want to do with that variable, you can do so in postExecute method or spawn another operation on its completion. – Ramandeep Nanda Jun 03 '15 at 04:52
0

Try to use this code, and make sure that your jsonstring is not null, because you won't post your complete code and I can't see if myResult variable was changed:

try {
                        JSONArray json = new JSONArray(jsonstring);

                        JSONObject json_customer = json.getJSONObject("customer");

                        return json_customer;
                        } catch (JSONException e) {
                        return null
                    }
Santiago
  • 1,744
  • 15
  • 23
0

For me it looks like problem with deserialization from String data to json's. We are lack of information what exactly data you are parsing. Consider using for this some more advanced json processing library lika Gson or Jackson. Usually its easier with them.

Sebastian Pakieła
  • 2,970
  • 1
  • 16
  • 24
0

It sounds like you are trying to read from myResult variable before the AsyncTask finishes retrieving it. To make sure it populates properly, put this into your onPostExecute function, after this line MyFragment.this.myResult = result;:

Log.i("my result value is: ", MyFragment.this.myResult.toString())

It should print it out in the LogCat if you are retrieving it correctly, and you should be able to access that variable after that.

On a separate note, consider using Volley or Retrofit or another networking plugin to make your life easier.

C0D3LIC1OU5
  • 8,600
  • 2
  • 37
  • 47
  • I put a Toast message in 'onPostExecute' just to check if 'myResult' was returning any value than 'null' and turns out that I get the value I wanted (which is not 'null'). But like you said, I'm trying to read the variable before the AsyncTask finishes...if so, how do I solve this problem? I mean, how do I get the value after the AsyncTask finishes? – BlueHatCoder Jun 02 '15 at 21:23
  • The convention is to show a loading indicator when you kick off the request and update the UI with your returned data after your 'onPostRequest' gets called, then hide the loading indicator. Here is one of the ways to show a loading indicator: http://stackoverflow.com/questions/12841803/best-way-to-show-a-loading-spinner – C0D3LIC1OU5 Jun 02 '15 at 21:30
  • In my 'onPreExecute' method I already use this loading indicator and in my 'onPostExecute' method i dismiss it, but still...same error...it tells me that my JsonArray is null (myResult) – BlueHatCoder Jun 02 '15 at 21:37
  • You can only access that variable from UI thread after onPostExecute function runs. Hold off on ANY use of that variable until then - do whatever you need to do with the data in that variable AFTER onPostExecute executes. Showing loading indicator is just to let users know your app is doing something in the background. Here is a good article that might help you understand AsyncTasks better: https://androidresearch.wordpress.com/2012/03/17/understanding-asynctask-once-and-forever/ – C0D3LIC1OU5 Jun 02 '15 at 21:43
0

Maybe you can use a clear way to transfer data back from the task to the fragment.

1) define an interface as the event listener to be called in the AsyncTask, like

    public interface TaskEventListener(){

        public void onTaskStarted(int messageId);

        public void onTaskStopped(int messageId, int resultCode);

        public void onDataReady(Object parameter);    
    }

2) let the fragment implement this EventListener, put the processing code in the onDataReady() function.

3) pass the fragment instance as the EventListener instance.

4) in the class extended from the AsyncTask, call the onTaskStarted() in the onPreExecute() function, call the onDataReady() and onTaskStopped() in the onPostExecute() function, and call the onTaskStopped() only in the onCancelled() function.

5) please use the weak references in the background task class to prevent crashing for referring the invalid UI component.

Zephyr
  • 6,123
  • 34
  • 33