2012-02-26 17 views
24

Ho provato in questo modo:Android: Come posso interrompere 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; 
    } 
}; 

ma non posso accedere kill() metodo!

risposta

37

Implementare invece il proprio meccanismo thread.kill(), utilizzando l'API esistente fornita dall'SDK. Gestisci la tua creazione di thread all'interno di un threadpool, e utilizzare Future.cancel() per uccidere il filo conduttore:

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

Annulla metodo comportarsi in modo diverso in base al compito condizione corrente, controllare l'API per maggiori dettagli.

+0

Grazie per la risposta. Questa volta non lo userò perché ho bisogno di più controllo di quanto l'API possa fornire. Grazie. –

+4

Questo causa un'eccezione di classe per me, Executors.newSingleThreadExecutor() non può essere di tipo ThreadPoolExecutor credo –

+0

Se 'longRunningTask' contiene un elenco di attività, come posso interrompere l'esecuzione di determinate attività? Potrebbero esserci molti thread in esecuzione contemporaneamente. – Stallman

3

changeColor è dichiarato come Runnable, che non ha un metodo kill().

È necessario creare la propria interfaccia che estende Runnable e aggiunge un metodo (pubblico) kill().

+0

Se creo una nuova classe il compilatore dice che c'è un problema con la "color_changer.postDelayed (ChangeColor, 150);" - changeColor non può essere risolto in variabile. –

+0

No; Intendo interfaccia. Tuttavia, farebbe funzionare anche una classe non anonima. Intendi "questo"? – SLaks

+0

Sì, intendevo quello, grazie. –

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

classe ......

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

Ti rendi conto che questa implementazione lascia il tuo Runnable che brucia i cicli della CPU? – stephen

8
mHandler.removeCallbacks(updateThread); 
+4

per favore, prova a descrivere la risposta – manetsus

+1

Questo è il modo più semplice per me. – bpiec

+1

In realtà, questa sembra essere la risposta corretta, poiché non è necessario creare il proprio Runnable personalizzato con tutto lo yada-yada o utilizzare ExecutorService. Ecco a cosa serve il metodo 'removeCallbacks'. È il più vicino a un 'clearTimeout' JavaScript, stesso modello. –

Problemi correlati