【问题标题】:How to show and hide an activity's ProgressBar from a AsyncTask?如何在 AsyncTask 中显示和隐藏 Activity 的 ProgressBar?
【发布时间】:2014-02-27 00:49:45
【问题描述】:

我创建了一个单独的类,它扩展了我在整个应用程序中用于通信的 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;
          }      
  }

提前致谢。

【问题讨论】:

    标签: android android-layout android-asynctask android-activity android-progressbar


    【解决方案1】:

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

    SendRequestExample.onPreExecute()
    

    并将其隐藏在:

    SendRequestExample.onPostExecute()
    

    方法。

    如果你的 SendRequestExample 对很多活动都是通用的,那么你可以让 MyActivity 实现接口,即:

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

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


    还有一个:不要在 UI 线程上的 asynctask 上使用 get(),在调用 'new SendRequest().execute().get();' 时。这会导致很多问题。它阻止 Android 使用的消息队列来处理负责响应用户点击、绘制小部件等的消息。几分钟后,这种 UI 线程阻塞将导致 ANR(Application Is Not Responding),系统将终止您的应用。

    【讨论】:

    • ProgressBar 在 my_activity_layout 中。我应该如何访问它。通过 findViewById 访问没有帮助。它不显示或隐藏 ProgressBar。我之前试过
    • 所以应用中的所有活动都将实现 ProgressBarAware?
    • 如果你的进度条在布局中,那么我想你别无选择。您可以为所有活动创建基本活动类。另外,很多时候 AsyncTasks 被用来返回一些数据给你的 Activity,这样的接口非常有用。
    • 我想我已经给了你所有的提示。还有一个:不要在 UI 线程上的 asynctask 上使用 get(),调用“new SendRequest().execute().get();”。这会导致很多问题。
    • 你是对的问题是我正在调用 execute.get()。但没有它我不能从 AsyncTask 串起来。这意味着我需要在我使用它的每个活动中使用 AsyncTask。这将是大量的代码重复。
    【解决方案2】:

    Every activity of my class uses this AsyncTask class for communication

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

    【讨论】:

      【解决方案3】:

      您不需要在Activity(s) 本身内声明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();
              ...
          }       
      }
      

      希望这会有所帮助。

      【讨论】:

      • 我也试过了,但是应用程序冻结了,当它解冻时,它会显示对话框并隐藏它
      • 我已经用了几十次了,而且总是很适合我。我不知道它可能有什么问题。
      • 我的应用程序在解冻前冻结并显示对话框。但我已经登录onPreExecute。它们会按时显示,但不会出现对话框。
      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 2016-12-19
        • 2019-08-02
        • 2021-12-16
        • 2017-05-31
        • 1970-01-01
        • 2012-04-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多