2016-12-27 4 views
0

Ich habe diese zwei Methoden zum Erstellen und Anhalten eines Threads. Der Thread wird jedoch weiterhin ausgeführt, auch nachdem die erste Methode aufgerufen wurde. (Ich erstelle ein Objekt der Klasse und rufe sie von einer anderen Klasse an).Kann Thread nicht stoppen

private Thread thread; 

public void stopAlarm() { 
    Log.i(LOG_TAG, "stopAlarm called"); 
    sendAlarm = false; 
    if (!thread.equals(null)) { 
     try { 
      thread.join(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 


public void triggerAlarm() { 
    Runnable alarmTest = new Runnable() { 
     @Override 
     public void run() { 
      while (sendAlarm) { 
       Log.i(LOG_TAG, String.valueOf(sendAlarm)); 
      } 
     } 
    }; 
    thread = new Thread(Test); 
    thread.start(); 
} 

stopAlarm Wenn der Thread bezeichnet wird, ist immer null, auch wenn es aufgerufen wird, nachdem triggerAlarm aufgerufen wird (Faden läuft).

+1

make 'sendAlarm'' volatile' –

+2

Zuerst schreibst du nie etwas wie thread.equals (null), denn wenn es gleich ist, bekommst du eine Ausnahme stattdessen thread == null second kannst du bitte mehr posten von Ihrem Code, um Ihr Problem besser zu verstehen – urag

+0

hat nicht geholfen, es ist immer noch wahr, auch nach dem Aufruf von stopAlarm() – user3742929

Antwort

1

Ihr Problem wird durch Thread-Bereich verursacht. Der Threadbereich wird erstellt, wenn Sie einen Thread mit denselben Variablen im Bereich erstellen, Sie diese Variablen jedoch nicht von außen ändern können. Die beste Methode zum Verwalten von Runnables in Android ist die Verwendung von Handler.

Handler handler = new Handler(); 
Runnable alarmTest = new Runnable() { 
    @Override 
    public void run() { 
     Log.i(LOG_TAG, String.valueOf(sendAlarm)); 
     handler.post(alarmTest, 5000); //wait 5 sec and run again 
     //you can stop from outside 
    } 
}; 

nach Definitionen, um die runnable zu starten:

handler.post(alarmTest,0); //wait 0 ms and run 

um die runnable zu stoppen:

handler.removeCallbacks(alarmTest); 

EDIT: wait-Anweisung mit Schleifen

EDIT: Komplettlösung

Handler handler = new Handler(); 
Runnable alarmTest = new Runnable() { 
    @Override 
    public void run() { 
     Log.i(LOG_TAG, String.valueOf(sendAlarm)); 
     handler.post(alarmTest, 5000); //wait 5 sec and run again 
     //you can stop from outside 
    } 
}; 

public void stopAlarm() { 
    Log.i(LOG_TAG, "stopAlarm called"); 
    handler.removeCallbacks(alarmTest); 
} 


public void triggerAlarm() { 
    handler.post(alarmTest,0); //wait 0 ms and run 
} 
+0

Funktioniert, aber friert meine GUI vollständig ein, wodurch stopAlarm() nutzlos wird. – user3742929

+1

Überprüfen Sie, ob Sie eine Menge von alertTest veröffentlichen, möglicherweise gibt es mehr als 1 Instanz – cokceken

+0

Die Methode, die handler.post (alarmTest) enthält, wird nur einmal aufgerufen. – user3742929

1

Abhängig von Ihrem Betriebssystem finden Sie möglicherweise Ihren Thread volatile kann dies beheben.

private volatile Thread thread; 

Allerdings - es gibt bessere Möglichkeiten, dies zu tun. Eine sehr nützliche ist die Verwendung eines kleinen (nur einen Eintrags) BlockingQueue, der poll ed vom laufenden Thread ist.

// Use a BlockingQueue to signal the alarm to stop. 
BlockingQueue<String> stop = new ArrayBlockingQueue<>(1); 

public void stopAlarm() { 
    stop.add("Stop"); 
} 


public void triggerAlarm() { 
    new Thread(() -> { 
     try { 
      while (stop.poll(1, TimeUnit.SECONDS) == null) { 
       // Stuff 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    }).start(); 
} 

Offensichtlich müssen Sie Rand Fällen wie verwalten, wo jemand anruft stopAlarm wenn kein Alarm läuft.

Verwandte Themen