Search code examples
javaandroidandroid-studioandroid-asynctaskcancellation

Stop the onPostExecute of an Async Task in java


I have the following code. My problem is, that I can't get the JSON.execute() to stop/cancel. I spend quite some time looking up possible answers but I wasn't able to find anything that really worked (e.g. JSON.cancel(true)). As soon as I turn the trackerswitch on, the AsnycTask starts running every 3 seconds just like it's supposed to. Is there a way to easily stop the AsyncTask from executing as soon as the trackerswitch is turned off?

    private boolean tracking = false;
    private Switch trackerswitch;
    private final Timer timer= new Timer();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.table_layout);
        final Handler handler=new Handler();
        final int delay = 4000;

        trackerswitch=findViewById(R.id.trackerswitch);
        trackerswitch.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                NetworkAccess JSON = new NetworkAccess();
                if(trackerswitch.isChecked()){
                    trackerswitch.setText("Tracking...");
                    tracking=true;
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            NetworkAccess JSON = new NetworkAccess();
                            JSON.execute();
                            handler.postDelayed(this, delay);
                        }
                    },delay);
                }
                else{
                    tracking=false;
                    trackerswitch.setText("Start Tracking");
                }
            }
        });

    }

}

This is what's called in the network class:

public class NetworkAccess extends AsyncTask<Void, Void, Void> {
    public ArrayList<String> alldata = new ArrayList<>();
    public ArrayList<String> locationlist = new ArrayList<>();
    int stride;
    String data;

    @Override
    protected Void doInBackground(Void... voids) {//4B4ADC

                SOME CODE WHICH ISN'T IMPORTANT FOR MY PROBLEM

                alldata.addAll(elementlist);
                locationlist.addAll(loctrack);

            }
        }
        catch(IOException | JSONException e){
            MainActivity.field1.setText(e.getClass().getCanonicalName());
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        MainActivity.field1.setText(String.format("%20s %20s", alldata.get(0), alldata.get(1)));
         COUPLE MORE OF THESE SETTEXT COMMANDS TO FILL A TABLE WITH DATA

    }
}

Thanks for your help!


Solution

  • handler.postDelayed() adds objects of the Runnable you provide to the message queue, to be run at the specified interval. You need to remove all the queued objects from the message queue in order to cancel the execution. Calling JSON.cancel(true) does not affect other objects that are already added to the queue.

    You'll have to retain a reference to your Runnable implementation and then call handler.removeCallbacks(r) to prevent further executions. Instead of using an anonymous class in handler.postDelayed().

    This documentation page sheds more light on the matter. Also refer this page for what happens when you call cancel(true) on an AsyncTask.