Reputation: 150
The problem is that i cant get the JSON result from my doInBackground. I know i need a handler and work with onPostExecute, but i cant make it work. I have a controller whos in charge of making the conection extending from AsyncTask. I call that controller.execute() on the main thread and it gives me an AsyncTask object instead of the JSON. This is the controller:
final MediaType JSON
= MediaType.parse("application/json; charset=utf-8");
@Override
protected String doInBackground(String... params){
try {
JSONObject newJson = new JSONObject(params.toString());
String dirArchivo = "http://10.0.2.2/SoulStoreProject/"+newJson.get("dir");
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(JSON, newJson.toString());
Request request = new Request.Builder()
.url(dirArchivo)
.post(body)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
} catch (IOException e) {
return e.getMessage().toString();
} catch (JSONException e) {
return e.getMessage().toString();
}
}
and this is the main class:
JSONObject requestObject = new JSONObject();
requestObject.put("nick", txtNicklog.getText().toString());
requestObject.put("password", txtPasslog.getText().toString());
requestObject.put("dir", "devolverJugador.php");
String result = Controller.execute(requestObject);
JSONObject resultFromAsyncTask= new JSONObject(result);
i dont know where to write the handler and how to call it from onPostExecute. Or if there is another way to solve it im open to sugestions
Upvotes: 1
Views: 958
Reputation: 111
The method execute() of an AsyncTask instance will not return to you the json start the assyncrhonous execution. So, this line String result = Controller.execute(requestObject);
will not wait until the AsynTask be finished to return the json to result variable, the asynctask is running in a second thread.
If you want to stop everything and wait the asynctask be finished, you have to call the method get: String result = Controller.execute(requestObject).get();
. But, have in mind that you will freeze your UI and it's not good! The best approach is run the AsynTask assynchrously and deal with the json in the method onPostExecute().
Upvotes: 1
Reputation: 6791
The problem here is about understanding how asynchronous tasks work. When you are calling Controller.execute(requestObject)
, it will run in background thread (off the main thread) and control will pass to the next line.
And thus, by the time control reaches JSONObject resultFromAsyncTask= new JSONObject(result);
, your response
is NOT yet fetched.
Along with that, I don't know how are you able to compile this:
String result = Controller.execute(requestObject);
Anyway, I would recommend you not to use AsyncTask
and instead use OkHttp
's asynchronous call to make the network requests.
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(JSON, newJson.toString());
Request request = new Request.Builder()
.url(dirArchivo)
.post(body)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
if(resonse.isSuccessful(){
//Running on UI thread, because response received is NOT on UI thread.
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
//use response to update any UI component
}
});
}
}
});
NOTE: I have assumed that you are using latest version of OkHttp
i.e., 3.2.0
Upvotes: 1