Reputation: 764
I've got a simple login screen. If you click "Login", a progress bar should appear while we wait for the AsyncTask in the background to check the login credentials.
If I run the code without the AsyncTask in the background, my progress bar appears immediately. However, if I use the AsyncTask, which I set up after I make my progress bar appear, the app freezes at the exact moment I click on "Login". Then it waits until the AsyncTask has got its result (get()
command) and only then it unfreezes, making my progress bar useless.
Is this a commonly known issue? How do you solve it?
This is how where I set up the AsyncTask, after I show the progress bar.
showProgress(true, "Logging in ...");
mAuthTask = new InternetConnection();
String arguments = "email="+mEmail+"&pwd="+mPassword;
boolean k = mAuthTask.makeConnection("ADDRESS", arguments, getBaseContext());
String f = mAuthTask.getResult();
And this is my AsyncTask. downloadUrl()
sets up an HttpURLConnection
. This works, I tested it.
private DownloadData data = new DownloadData();
public boolean makeConnection(String url, String arguments, Context context) {
if(isWifi(context) || isMobile(context)) {
argsString = arguments;
data.execute(url);
return true;
} else {
return false; //No network available.
}
}
public String getResult() {
try {
return data.get();
} catch (InterruptedException e) {
return "Error while retrieving data.";
} catch (ExecutionException e) {
return "Error while retrieving data.";
}
}
private class DownloadData extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... url) {
try {
return downloadUrl(url[0]);
} catch (IOException e) {
return "Unable to retrieve data.";
}
}
Upvotes: 1
Views: 473
Reputation: 7860
Do it like:
@Override
protected void onPreExecute() {
Asycdialog.setMessage("Working");
Asycdialog.getWindow().setGravity(Gravity.CENTER_VERTICAL);
Asycdialog.getWindow().setGravity(Gravity.CENTER_HORIZONTAL);
Asycdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
Asycdialog.setCancelable(false);
//Dialog Show
Asycdialog.show();
super.onPreExecute();
And then in onPostExecute:
protected void onPostExecute(String result) {
// hide the dialog
Asycdialog.dismiss();
super.onPostExecute(result);
}
To use the same Async task from Different classes:
class MainActivity{
new MyTask().execute();
}
class DifferentActivity {
new MyTask().execute();//a new instance
}
class MyTask extends AsyncTask{
public MyTask(Context context){
}//Pass in context.
}
Pass the context to the constructor, if you want a consistent Progress dialog.
TO publish the progress from doInBackground you can use the following:
publishProgress(progress);
Asycdialog.setMax(lines);
Asycdialog.incrementProgressBy(1);
Where progress is a string, lines are the max number of items.
Upvotes: 2
Reputation: 157457
your issue is related to the fact that you are calling getResult
from the UI Thread. getResult
calls data.get()
that is a blocking operation. That's why you are getting a freeze. Your UI Thread
is waiting for get()
to complete and it is unable to draw everything else
Upvotes: 2
Reputation: 133560
You should not call get()
it blocks the ui waiting for the result to be returned making asynctask no more asynchronous.
You have
private DownloadData data = new DownloadData();
and you have
data.get(); // this why it freezes
and
private class DownloadData extends AsyncTask<String, Void, String>
http://developer.android.com/reference/android/os/AsyncTask.html#get()
You only need
data.execute(url);
And if your asynctask is an inner class of activity class you can return result in doInbackground
and update ui in onPostExecute
. If not you can use interface as a callback to the activity to return the result.
Upvotes: 2