【问题标题】:Cancel ProgressDialog and stop thread取消 ProgressDialog 并停止线程
【发布时间】:2013-03-12 11:31:52
【问题描述】:

我有一个线程运行多个操作一次,我想在用户取消ProgressDialog 时停止它。

public void run() {

    //operation 1

    //operation 2

    //operation 3

    //operation 4
}

这个线程只运行一次,所以我不能实现一个循环来检查他的线程是否应该还在运行。

这是我的进度对话框:

//Wait dialog
m_dlgWaiting = ProgressDialog.show(m_ctxContext, 
                                    m_ctxContext.getText(R.string.app_name), 
                                    m_ctxContext.getText(R.string.msg_dlg_analyse_pic), 
                                    true, //indeterminate
                                    true,
                                    new OnCancelListener() {
                                        @Override
                                        public void onCancel(DialogInterface dialog) {
                                            m_bRunning = false;
                                        }
                                    });

由于我不知道如何停止线程,因此通过循环对线程的操作进行排序以查看它是否应该仍在运行是否正确,或者有更好的方法吗?

public void run() {
    int op = 0;
    while(m_bRunning) {
       switch(op) {
          case 0 :
              //operation 1
              break;
          case 1 :
              //operation 2
              break;
          case 2 :
              //operation 3
              break;
          case 3 :
              //operation 4
              break;
       }
       op++;
    }
}

即使使用此解决方案,如果线程中的操作过多,也可能难以对操作进行排序。有没有更好的方法来实现这一点?

【问题讨论】:

    标签: android multithreading progressdialog


    【解决方案1】:

    使用回调或 AsyncTask

    http://developer.android.com/reference/android/os/AsyncTask.html

    final AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
            private ProgressDialog dialog;
    
            @Override
            protected void onPreExecute()
            {
                this.dialog = new ProgressDialog(context);
                this.dialog.setMessage("Loading...");
                this.dialog.setCancelable(true);
                this.dialog.setOnCancelListener(new DialogInterface.OnCancelListener()
                {
                    @Override
                    public void onCancel(DialogInterface dialog)
                    {
                        // cancel AsyncTask
                        cancel(false);
                    }
                });
    
                this.dialog.show();
    
            }
    
            @Override
            protected Void doInBackground(Void... params)
            {
                // do your stuff
                return null;
            }
    
            @Override
            protected void onPostExecute(Void result)
            {
                //called on ui thread
                if (this.dialog != null) {
                    this.dialog.dismiss();
                }
            }
    
            @Override
            protected void onCancelled()
            {
                //called on ui thread
                if (this.dialog != null) {
                    this.dialog.dismiss();
                }
            }
    };
    task.execute();
    

    【讨论】:

    • 谢谢,我不确定我是否可以使用 AsyncTasks,因为这些操作是同步的,但我会用这个替换我的线程。顺便说一句,如果网络操作在任务中,将这个 AsyncTask 作为我的活动的成员是一个好习惯吗?
    • 可以,可以作为成员使用,但是每次执行前必须初始化(一个实例可以执行一次)。
    【解决方案2】:

    你可以像下面这样使用 Asynctask

    FetchRSSFeeds fetchRss = new FetchRSSFeeds()
    fetchRss.execute();
    
    private class FetchRSSFeeds extends AsyncTask<String, Void, Boolean> {
    
        private ProgressDialog dialog = new ProgressDialog(HomeActivity.this);
    
        /** progress dialog to show user that the backup is processing. */
        /** application context. */
    
        protected void onPreExecute() {
            this.dialog.setMessage(getResources().getString(
                    R.string.Loading_String));
            this.dialog.show();
        }
    
        protected Boolean doInBackground(final String... args) {
            try {
    
                /**
                 * Write your RUN method code here
                 */
               if (isCancelled()) {
    
                 if (dialog.isShowing()) {
                    dialog.dismiss();
                 }
               }
    
                return true;
            } catch (Exception e) {
                Log.e("tag", "error", e);
                return false;
            }
        }
    
        @Override
        protected void onPostExecute(final Boolean success) {
    
        }
    }
    

    当您想取消后台进程时,请执行以下操作

    if (fetchRss.getStatus() == AsyncTask.Status.RUNNING) {
        fetchRss.cancel(true);
    }
    

    【讨论】:

      猜你喜欢
      • 2011-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多