Issue
I have the code that sends requests to REST API in AsyncTask.
Also, I have a ProgressDialog initialization in preExecute()
and its dismission in postExecute()
.
I want ProgressDialog to show an indeterminate spinner (you know, that loading animation), but I need to get a result too. get()
blocks the main thread where I'm invoking it in - what's the workaround for that case?
Main thread (main activity)
LoginTask task_login = new LoginTask();
AsyncTask<String, Void, JSONObject> response = task_login.execute(et_username.getText().toString(), et_password.getText().toString());
try {
JSONObject json = response.get();
Toast.makeText(MainActivity.this, json.toString(), Toast.LENGTH_SHORT).show();
} catch (InterruptedException e) {
Toast.makeText(MainActivity.this, "Interrupted.", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
AsyncTask (dummy doInBackground):
public class LoginTask extends AsyncTask<String, Void, JSONObject> {
private LoginTask self = this;
private ProgressDialog progressDialog;
@Override
protected JSONObject doInBackground(String... params) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = ProgressDialog.show(MainActivity.context,
"Logging in...", "");
progressDialog.setButton(DialogInterface.BUTTON_NEUTRAL,
MainActivity.context.getResources().getResourceEntryName(R.string.dialog_button_cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
self.cancel(true);
}
});
}
@Override
protected void onPostExecute(JSONObject jsonObject) {
super.onPostExecute(jsonObject);
progressDialog.dismiss();
}
}
Solution
Please look at the usage of AsyncTask https://developer.android.com/reference/android/os/AsyncTask#usage
There is a callback function onPostExecute
which returns (as parameter) the value you requested:
private class RestTask extends AsyncTask<Object, Object, String> {
protected String doInBackground(Object... args) {
// this happend on background thread
return downloadData();
}
protected void onPreExecute() {
// this happend on UI thread
showSpinner();
}
protected void onPostExecute(String result) {
// this happend on UI thread
hideSpinner();
doSomethingWithDownloadResult(result);
}
}
Usage:
new RestTask().execute()
As you edited the question, this:
try {
JSONObject json = response.get();
Toast.makeText(MainActivity.this, json.toString(), Toast.LENGTH_SHORT).show();
} catch (InterruptedException e) {
Toast.makeText(MainActivity.this, "Interrupted.", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
should be called in previous Tasks onPostExecute
method, this way you will not block you UI with get
method waiting on login result.
Answered By - Gaskoin
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.