如何在AsyncTask中显示和隐藏Activity的ProgressBar?

3

我创建了一个单独的类,它扩展了AsyncTask,并在整个应用中用于通信。我的每个活动都使用这个AsyncTask类进行通信。当通信正在进行时,我想显示ProgressBar(活动指示器)。如果我在使用通信类的活动中显示和隐藏ProgressBar,那么ProgressBar会在通信完成之前冻结。有没有办法从AsyncTask类中在屏幕中间显示一个ProgressBar,以便它不会冻结,用户知道后台正在发生一些事情。我正在使用以下代码:

  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);
         }
      }
  }

而 AsyncTask 类是:

  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.

4个回答

5

你应该在以下位置显示进度条:

SendRequestExample.onPreExecute()

并将其隐藏在:

SendRequestExample.onPostExecute()

方法。

如果您的SendRequestExample适用于许多活动,那么您可以使MyActivity实现接口,如下:

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

需要将ProgressBarAware引用传递给您的AsyncTask。在配置更改期间,重要的是在AsyncTask中更新此引用,这意味着每次Activity.onCreate在配置更改后执行。


还有一点:不要在UI线程上使用asynctask的get()方法,在调用“new SendRequest()。execute()。get();”时。这会导致许多问题。它会阻塞消息队列,该队列用于处理响应用户点击、绘制小部件等消息,几分钟后,这种UI线程阻塞将导致ANR(应用程序未响应),系统将终止您的应用程序。


进度条位于我的活动布局中。我该如何访问它?使用findViewById访问没有帮助,它无法显示或隐藏进度条。我之前尝试过。 - Piscean
所有应用程序中的活动都将实现ProgressBarAware吗? - Piscean
如果您的进度条在布局中,那么我想您别无选择。您可以为所有活动创建基础活动类。此外,很多时候AsyncTasks用于将一些数据返回给您的活动,这种接口非常有用。 - marcinj
1
我认为我已经给了你所有的提示。再来一个:不要在UI线程上使用asynctask的get()方法,在调用“new SendRequest().execute().get();”时。这会引起很多问题。 - marcinj
请将您的评论作为答案写下,以便我接受它。感谢您的帮助。 - Piscean
显示剩余2条评论

1

我的课程中的每个活动都使用这个AsyncTask类进行通信

在AsyncTask中使用ProgressDialog

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();
        .....
    }

}

0

您不需要在Activity内部声明ProgressDialog。相反,您可以像这样在AsyncTask中创建ProgressDialog

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();
        ...
    }       
}

希望这有所帮助。

我也尝试过这个,但应用程序会冻结,当它解冻时,它会显示对话框并隐藏它。 - Piscean
我已经使用过它几十次,而且总是完美地工作。我不知道可能出了什么问题。 - SMR
我的应用程序会在冻结一段时间后显示对话框,但是我在 onPreExecute 中有日志。它们按时显示,但对话框不出现。 - Piscean

0
在XML中隐藏您的ProgressBar并按照以下步骤进行操作。
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);
    }

}

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接