2012-02-26 10 views
24

he intentado de esta manera:Android: ¿Cómo puedo detener Runnable?

private Runnable changeColor = new Runnable() { 
    private boolean killMe=false; 
    public void run() { 
     //some work 
     if(!killMe) color_changer.postDelayed(changeColor, 150); 
    } 
    public void kill(){ 
     killMe=true; 
    } 
}; 

pero no puedo acceder kill() método!

Respuesta

37

En su lugar, implemente su propio mecanismo thread.kill(), utilizando la API existente proporcionada por el SDK. Administrar su creación de hilos dentro de un threadpool, y utilizar Future.cancel() para matar el hilo conductor:

ExecutorService threadPoolExecutor = Executors.newSingleThreadExecutor(); 
Runnable longRunningTask = new Runnable(); 

// submit task to threadpool: 
Future longRunningTaskFuture = threadPoolExecutor.submit(longRunningTask); 

... ... 
// At some point in the future, if you want to kill the task: 
longRunningTaskFuture.cancel(true); 
... ... 

Cancelar método se comportan de manera diferente en función de su estado de ejecución de tareas, consulte la API para obtener más detalles. clase

+0

Gracias por su respuesta. No usaré esto esta vez porque necesito más control del que API puede proporcionar. Gracias. –

+4

Esto causa una excepción de clase de lanzamiento para mí, Executors.newSingleThreadExecutor() no puede ser de tipo ThreadPoolExecutor Creo –

+0

Si 'longRunningTask' contiene una lista de tareas, ¿cómo puedo abortar la ejecución de ciertas tareas? Puede haber muchas secuencias ejecutándose simultáneamente. – Stallman

3

changeColor se declara como Runnable, que no tiene un método kill().

Debe crear su propia interfaz que extienda Runnable y agregue un método (público) kill().

+0

Si se crea una nueva clase entonces el compilador dice que no hay problema con "color_changer.postDelayed (changeColor, 150);" - changeColor no se puede resolver a variable. –

+0

No; Me refiero a la interfaz. Sin embargo, hacer una clase no anónima también funcionaría. ¿Te refieres a 'esto'? – SLaks

+0

Sí, quise decir eso, gracias. –

14
public abstract class StoppableRunnable implements Runnable { 

    private volatile boolean mIsStopped = false; 

    public abstract void stoppableRun(); 

    public void run() { 
     setStopped(false); 
     while(!mIsStopped) { 
      stoppableRun(); 
      stop(); 
     } 
    } 

    public boolean isStopped() { 
     return mIsStopped; 
    } 

    private void setStopped(boolean isStop) {  
     if (mIsStopped != isStop) 
      mIsStopped = isStop; 
    } 

    public void stop() { 
     setStopped(true); 
    } 
} 

......

private Handler mHandler = new Handler(); 

public void onStopThread() { 
    mTask.stop();  
    mHandler.removeCallbacks(mTask); 
} 

public void onStartThread(long delayMillis) { 
    mHandler.postDelayed(mTask, delayMillis); 
} 

private StoppableRunnable mTask = new StoppableRunnable() { 
    public void stoppableRun() {   
        ..... 
      onStartThread(1000);     
     } 
    } 
}; 
+6

¿Se da cuenta de que esta implementación deja su Runnable quemando ciclos de CPU? – stephen

8
mHandler.removeCallbacks(updateThread); 
+4

por favor, intente describir la respuesta – manetsus

+1

Esta es la forma más fácil para mí. – bpiec

+1

En realidad, esta parece ser la respuesta correcta, ya que no tiene que crear su propio Runnable personalizado con todos los yada-yada o usar el ExecutorService. Para eso está el método 'removeCallbacks'. Es lo más parecido a JavaScript 'clearTimeout', el mismo patrón. –

Cuestiones relacionadas