如何确保只运行一个[0,1] AsyncTask?

时间:2017-05-18 04:57:28

标签: android android-asynctask

目前我有这个简单的演示应用程序。它有一个按钮,一旦点击,创建一个新的AsyncTask,等待3秒后生成一个随机名称并显示它

enter image description here

但是,如果您快速连续多次单击该按钮,新的AsyncTasks将排在第一个后面 - 串行执行。

是否可以禁用队列功能

使得最后一个AsyncTask是唯一一个被执行的(并将立即启动 - 从而取消之前的任何AsyncTask)

以下是我目前拥有的代码,感谢您的帮助

package com.example.www.android_async_task;

import android.os.AsyncTask;
import android.os.SystemClock;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.util.Random;

public class MainActivity extends AppCompatActivity
{
    public Button   NAME_BUTTON;
    public TextView NAME_DISPLAY;

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

        NAME_BUTTON  = (Button)   findViewById(R.id.bt_name_button);
        NAME_DISPLAY = (TextView) findViewById(R.id.tv_name_display);

        NAME_BUTTON.setOnClickListener(name_button_listener);
    }

    public View.OnClickListener name_button_listener = new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            Log.d("MainActivity", "new CustomTask().execute();");

            new CustomTask().execute();
        }
    };

    public class CustomTask extends AsyncTask<Void, Void, Void>
    {
        @Override
        protected Void doInBackground(Void... params)
        {
            Log.d("MainActivity", "SystemClock.sleep(3000);");

            SystemClock.sleep(3000);

            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid)
        {
            String[] names = {"Frank L. Lane",
                              "Kevin C. Payne",
                              "Barbara R. Junker",
                              "Nicholas S. Jones",
                              "Ralph M. Crump",
                              "Loretta T. Francis",
                              "Alisha M. Williams",
                              "Daniel D. Hardy",
                              "Chadwick M. Gantz"};

            String name = names[new Random().nextInt(names.length)];

            Log.d("MainActivity", "NAME_DISPLAY.setText(name);");

            NAME_DISPLAY.setText(name);
        }
    }
}

3 个答案:

答案 0 :(得分:1)

简单方法是声明全局变量boolean IsAsyncRunning=false

 CustomTask customTask;  // globalVariable

@Override
    public void onClick(View v)
    {
        Log.d("MainActivity", "new CustomTask().execute();");

           if(!IsAsyncRunning){

             customTask= new CustomTask();
             customTask.execute();
             IsAsyncRunning=true;
      }
      else{
           if (customTask != null && customTask.getStatus() != AsyncTask.Status.FINISHED)
                            customTask.cancel(true);
           customTask= new CustomTask();
             customTask.execute();
             IsAsyncRunning=true;

       }
    }

并且在postexecute中将其设为false

   @Override
    protected void onPostExecute(Void aVoid)
    {
        String[] names = {"Frank L. Lane",
                          "Kevin C. Payne",
                          "Barbara R. Junker",
                          "Nicholas S. Jones",
                          "Ralph M. Crump",
                          "Loretta T. Francis",
                          "Alisha M. Williams",
                          "Daniel D. Hardy",
                          "Chadwick M. Gantz"};

        String name = names[new Random().nextInt(names.length)];

        Log.d("MainActivity", "NAME_DISPLAY.setText(name);");

        NAME_DISPLAY.setText(name);
       IsAsyncRunning=false;
    }

答案 1 :(得分:1)

试试这个:

此处,只要Async启动,请禁用按钮单击,完成名称生成后,再次启用

public class CustomTask extends AsyncTask<Void, Void, Void>
    {

       @Override
        protected void onPreExecute() {
            NAME_BUTTON.setClickable(false);
        }

        @Override
        protected Void doInBackground(Void... params)
        {
            Log.d("MainActivity", "SystemClock.sleep(3000);");

            SystemClock.sleep(3000);

            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid)
        {
            String[] names = {"Frank L. Lane",
                              "Kevin C. Payne",
                              "Barbara R. Junker",
                              "Nicholas S. Jones",
                              "Ralph M. Crump",
                              "Loretta T. Francis",
                              "Alisha M. Williams",
                              "Daniel D. Hardy",
                              "Chadwick M. Gantz"};

            String name = names[new Random().nextInt(names.length)];

            Log.d("MainActivity", "NAME_DISPLAY.setText(name);");

            NAME_DISPLAY.setText(name);
            NAME_BUTTON..setClickable(true);
        }
    }

答案 2 :(得分:0)

启动前检查AsyncTask是否已经运行。如果它没有运行,则执行AsyncTask。另一种方法是在onClick中单击禁用按钮,然后在onPostExecute(AsyncTask)中再次启用按钮。这样用户只能点击一次。执行期间用户无法点击按钮。

   CustomTask customTask;    //declare global
    @Override
    public void onClick(View v)
    {
         customTask=  new CustomTask();
         // 
         if(customTask.getStatus() != AsyncTask.Status.RUNNING) 
         {
          customTask.execute();
         }          
        }