Marco7757
Marco7757

Reputation: 764

AsyncTask Delays Program Flow / Screen Freezes

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

Answers (3)

Junaid
Junaid

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

Blackbelt
Blackbelt

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

Raghunandan
Raghunandan

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

Related Questions