4

Here is my process and problem:

  1. In this application you click a Menu button

  2. From this Menu you press a toggle button, which starts an Async-Task (makes a tone sound every 30 seconds). This task is to run constantly when the toggle is checked, and cancel when it is unchecked. This work's fine to start and stop the process as long as you remain in the Menu window.

  3. Check the toggle box!

  4. If the window is peeled back and Menu is opened again, my save state for the toggle is Checked and the process is still running. However I THINK I lost access to that instance of the Async Task. Which might be why unchecking the toggle will then crash the program?
    myTask.cancle(true); may be like a lost reference and my Asynch-Task is now flowing out in the void where I can no longer call to or control it!

What can I do to grab the Async task and cancel it in this situation?

TL,DR; If I spawn an async task from one activity (mTask = new ...), but then leave that activity, how can I still access mTask?

2 Answers2

0

You should stop the a sync task as soon as the activity destroyed/stoped if there is no need in it,

@Override
public void onStop(){
    mTask.cancel();
}

see this for more info about canceling a sync task Android - Cancel AsyncTask Forcefully

Community
  • 1
  • 1
Kirill Kulakov
  • 10,035
  • 9
  • 50
  • 67
0

I think you should not use the AsyncTask API, which is intended for running a time consuming task in a background thread and provides hooks to update the UI when it finishes or has intermediate results.

You can simply use a Runnable and the singleton pattern to locate the instance across activities constructions and destructions. Something like (singleton boilerplate omitted for brevity)

public class Player implements Runnable {

  public static void start() {}

  @Override
  public void run() {
    while (alive) {
      playSound();
      sleep();
    }
  }

  public static void stop() {}

  public static boolean isAlive() {}

}

Then, when you initialize your widgets:

checkbox.setChecked(Player.isAlive());
checkbox.setOnCheckedStateChangeListener(new OnCheckedChangeListener(){
  @Override
  public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    if (isChecked)
      Player.start();
    else
      Player.stop();
  }
});

This way your background thread is completely independent from any Activity which started it.

Raffaele
  • 20,627
  • 6
  • 47
  • 86
  • What all could cause the runnable (thread?) to end itself aside from: 1. explicitly terminating via unchecking the toggle; 2. Force closing the entire app; 3. Restarting phone; ?? If I recall, I was using async task because I needed this process to run constantly once activated, even while the app is not focused on screen... To run behind anything else that could happen for as long as the phone is on. – iForgotMyLogin Nov 12 '12 at 00:30
  • This thread only ends when the flag is checked. Once it is started, it's lifecycle is independent from the Activity. Obviously, if you force kill the app or restart the phone, the whole process dies and the thread is shut down. However the very same happens with AsyncTask and Services too, except that with Services you can declare them to start automatically when something happens – Raffaele Nov 12 '12 at 09:32