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()
?