AlanSTACK
AlanSTACK

Reputation: 6065

How to make sure only one [0,1] AsyncTask is ever running?

currently I have this simple demo application. It has a button that once clicked, creates a new AsyncTask that waits 3 seconds before generating a random name and displaying it

enter image description here

However, if you click the button multiple times in quick succession, new AsyncTasks get queued behind the first one - executing serially.

Is it possible to disable the queue feature,

such that the last AsyncTask is the only one that gets executed (and will start immediately - thus canceling any AsyncTask before it)

Below is the code I currently have, thanks for any help

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

Upvotes: 0

Views: 672

Answers (3)

Manohar
Manohar

Reputation: 23404

Simple method is to declare a global variable 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;

       }
    }

and in postexecute make it 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;
    }

If your CustomTask extends AsyncTask you could write :

public void execute(){
    super.execute();
    isAsyncRunning= true;
}

so you don't have to manually set the boolean value.

Upvotes: 2

Sasi Kumar
Sasi Kumar

Reputation: 13348

Check before start AsyncTask is already running or not.if its not running execute AsyncTask. Another way after click disable button in onClick then enable button again in onPostExecute(AsyncTask). so that user can able click only one time.During the execution user cant click button.

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

Upvotes: 1

Divyesh Patel
Divyesh Patel

Reputation: 2576

try this:

Here as soon as Async starts, disable button click, and after completing name generate, enable it again

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

Upvotes: 2

Related Questions