-1

This question has actually been asked numerous times before. I have looked through 9 questions (1, 2, 3, 4, 5, 6, 7, 8, 9) and all their answers. None of them work or relate to my problem.

I have the Asynctask class as an inner class inside my MainActivity. So here is my MainActivity Class in which I have only implemented onPostExecute() and doInBackground() (I have omitted code relating to connecting with GoogleApiClient.

public class MainActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // inflate views
        // create instance of GoogleApiClient
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        // start the background thread
        new Distance().execute();
    }

    public class Distance extends AsyncTask<Void, Void, String[]> {
        public Distance() {
        }

        @Override 
        protected String[] doInBackground(Void...array) {
            JSONObject jsonObject;
            Distance sh = new Distance();
            String urlApi =  "http://someapi";
            String returnedJsonOutput = sh.makeServiceCall(urlApi);
            String[] stringPack = new String[3];
            // note: so far so good and I omitted the makeServiceCall method

            if (returnedJsonOutput != null) {
                try {
                   // turn the output into json object for parsing
                   jsonObject = new JSONObject(returnedJsonOutput);

                   // parse it out
                   JSONArray rowArray = jsonObject.getJSONArray("rows");
                   JSONArray elementArray = rowArray.getJSONArray(1);
                   JSONObject distanceObject = elementArray.getJSONObject(1);
                   JSONObject durationObject = elementArray.getJSONObject(2);

                   // create String array to return
                   stringPack[2] = distanceObject.getString("text");
                   stringPack[3] = durationObject.getString("text");

                   //this is exactly the point in which the background thread jumps off and switches to the UI thread resulting in onPostExecute() callback being triggered with an empty result argument
                   stringPack[0] = jsonObject.getString("origin_addresses");
                   stringPack[1] = jsonObject.getString("destination_addresses");

                   return stringPack;

                } catch (final JSONException e) {
                    Log.e(TAG, "JSON Parse Error: " + e.getMessage());
                    return null;
                }
            }
            return stringPack
        } 
    }// end of doInBackground()

    @Override
    protected void onPostExecute(String[] result) {
        mOrigin.setText(result[0]);
        mDestination.setText(result[1]);
        mDistance.setText(result[2]);
        mDuration.setText(result[3]);
    }
}

FYI, the actual http request and result of the API call is here.

When I run it, it produces a runtime error (nullpointerexception) where the variable I expect to be filled from the result of doInBackground() is empty when it is called onPosteExecute(). When I look at the execution in debug mode, I see the background thread falling off halfway through the code in doInBackground() and switching immediately to the UI thread in onPostExecute(). So the variable I need to be filled by the result of doInBackground() does not contain the data I need - hence the runtime error.

I look at the docs and it is clear that onPostExecute() is only called on the UI thread when the background thread completes executing the last line of code on doInBackground().

So my question is: why is the background thread not executing everything in the block of code inside doInBackground() before it starts executing onPostExecute()?

Community
  • 1
  • 1
Gil
  • 515
  • 2
  • 10
  • 24
  • 2
    It's simple your code throws runtime exception which is caught by catch caluse in that method. after which the return statement will be executed with no data. Try to look at the cause of exception, everything else is working fine. – KunalK Feb 02 '17 at 12:19
  • @KunalK I changed the catch clause to return the stringPack[] array with some fake data. but the same runtime error is showing even though I am not returning null... – Gil Feb 02 '17 at 12:27
  • `onPostExecute(String[] result)`. `result ` can be `null`. But you are not checking for null and blindly using up to `resul[3`. That will give you `NullPointerException`s. WHich make you think that the sequence is not ok. – greenapps Feb 02 '17 at 12:28

1 Answers1

1

If your code was completing normally without error, it would return the empty array (of size 3) you specifically define earlier.

Your Catch block returns null so it is highly likely that an error is occurring which you trap and then handle by returning null.

Place a breakpoint in your Catch bloack and investigate the cause of the exception.

Kuffs
  • 35,581
  • 10
  • 79
  • 92