如何在不导致UI冻结的情况下延迟执行某项任务

时间:2015-03-22 01:52:05

标签: android multithreading android-asynctask

所以我有一个Asynctask类,在点击一个按钮后5秒执行下一个动作。

mButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            delay = new delayMessageAsyncTask();
            delay.setProgressBar(delaySendProgressWheel);
            delaySendProgressWheel.setProgress(0);
            delaySendProgressWheel.setSpinSpeed(0.21f);
            mButton.setVisibility(ImageView.GONE);
            delaySendProgressWheel.setVisibility(ProgressWheel.VISIBLE);
            delay.execute();

            //performAction();
        }
    });


class delayMessageAsyncTask extends AsyncTask<Void, Integer, Void> {
    int myProgress;
    @Override
    protected void onPreExecute() {
        myProgress = 0;
        super.onPreExecute();
    }

    @Override
    protected void onPostExecute(Void result) {
        edit_text.setText("");
        mButton.setVisibility(ImageView.VISIBLE);
        delaySendProgressWheel.setVisibility(ProgressWheel.GONE);
        msgAdapter.setArrayList(message);
        msgAdapter.notifyDataSetChanged();
        listView.smoothScrollToPosition(msgAdapter.getCount()-1);
        super.onPostExecute(result);
    }

    @Override
    protected Void doInBackground(Void... params) {
        while(myProgress<100){
            myProgress+=20;
            publishProgress(myProgress);
            try {
                Thread.sleep(1000);
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        performAction();
        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        delaySendProgressWheel.setProgress((float)values[0]);
    }

问题是,performAction()非常复杂,因为它包含后台线程和UI线程,因此我必须在doInBackground内放置一部分并更新UI onPostExecute。但正如我所说,只有在5秒之后才能执行动作,因此它会在到达onPostExecute之前停止一段时间。我已尝试将performAction()移至onPostExecute,但会导致用户界面冻结。理想情况下,我想知道在execute()中使用onClick()方法之后是否有任何方法可以停止执行代码,因此我可以将performAction()放在那里。

2 个答案:

答案 0 :(得分:3)

按下单击后,您可以使用处理程序添加延迟:

    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
      public void run() {
        // exec code here
      }
    }, 5000);

答案 1 :(得分:1)

您可以使用:

  Handler mHandler;

  public void postHandler() {
    mHandler = new Handler();
    mHandler.postDelayed(mRunnable, 5000);
  }

  private Runnable mRunnable = new Runnable() {

    @Override
    public void run() {
      /** Do something **/

        new AsyncTask<Void,Void,Void>(){

        @Override
        protected Void doInBackground(Void... params) {

            performAction();
            return null;
        }

       }.execute();
    }
  };