Question

I have a created a separate class which extends AsyncTask which i am using for communication in my whole app. Every activity of my class uses this AsyncTask class for communication. I want to show ProgressBar (activity indicator) whenever communication is in progress. If i show and hide ProgressBar in activity which uses communication class then ProgressBar freezes until communication is done. Is there any way to show a ProgressBar in middle of screen from AsyncTask class so it doesn't freeze and user knows that there is something going on in background. I am using following code:

  public class MyActivity extends Activity {

      ProgressBar spinner;

      @Override
      protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.my_activity_layout);

         spinner = (ProgressBar)findViewById(R.Id.progressbar); 
         spinner.setVisibility(ProgressBar.INVISIBLE);
      }

      protected void onResume()
      {
         super.onResume();
      }

      public void buttonClickHandler(View target){
         try{
            spinner.setVisibility(ProgressBar.VISIBLE);
            String output = new SendRequest().execute().get();      
            spinner.setVisibility(ProgressBar.INVISIBLE);           
         }catch(Exception ex){
            System.out.println("buttonClickHandler exception: "+ex);
         }
      }
  }

and AsyncTask class is:

  public class SendRequestExample extends AsyncTask<ArrayList<String>, Void, String> {
      public String result; 

          protected String doInBackground(ArrayList<String>... params) {

              // doing communication 
              ...

              return result;
          }      
  }

Thanks in advance.

Was it helpful?

Solution

You should show your progress bar in :

SendRequestExample.onPreExecute()

and hide it in:

SendRequestExample.onPostExecute()

methods.

If your SendRequestExample is universal for many activities, then you can make MyActivity implement interface, ie:

interface ProgressBarAware {
  void showProgressbar();
  void hideProgressbar();
}

and pass ProgressBarAware reference to your AsyncTask. Its important to update this reference in AsyncTask during configuration changes, that means every time your Activity.onCreate executes after config change.


One more: dont use get() on asynctask on UI thread, in call 'new SendRequest().execute().get();'. This causes lots of problems. It block message queue that is used by Android to process messages responsible for reacting to user clicks, drawing widgets, and lots more. After few minutes, such UI thread blocking will end up in ANR (Application Is Not Responding), and system will terminate your app.

OTHER TIPS

Every activity of my class uses this AsyncTask class for communication

Use ProgressDialog inside AsyncTask

public class MyAsyncTask extends AsyncTask<Void, Void, Void> 
{
    private ProgressDialog pDialog ;


    protected void onPreExecute() {
        m_logger.d("onPreExecute");
        pDialog = new ProgressDialog(m_applicationContext);
        pDialog.setCancelable(false);
        pDialog.show();
                ....
    }

    protected void onPostExecute(Intent result) 
    {
        if( null != pDialog)
            pDialog.dismiss();
        .....
    }

}

You dont need to declare ProgressDialog inside the Activity(s) itself. instead you can create ProgressDialog inside AsyncTask like this.

public class SendRequestExample extends AsyncTask<ArrayList<String>, Void, String> {
    ProgressDialog pdialog = new ProgressDialog(yourcontexthere);
    ....
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pdialog.setCancelable(false);
        pdialog.setTitle("Please wait.");
        pdialog.setMessage("doing stuff...");
        pdialog.show();
    }
    @Override
    protected String doInBackground(String... params) {
         // doing stuff
        ...
        return result;
    }
    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        if(pdialog.isShowing())
            pdialog.dismiss();
        ...
    }       
}

Hope this helps.

Hide your ProgressBar in the XML and follow the below steps.

public class MainActivity extends Activity {

ProgressBar bar;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    bar = (ProgressBar) findViewById(R.id.progressBar1);
    new MyTask().execute();
}

class MyTask extends AsyncTask<Void, Void, Void>{

    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        bar.setVisibility(View.VISIBLE);
        super.onPreExecute();
    }

    @Override
    protected Void doInBackground(Void... params) {
        // TODO Auto-generated method stub
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        bar.setVisibility(View.GONE);
    }

}

}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top