У меня есть следующий поток в моем классе обслуживания.
public class MyLocalThread extends Thread {
@Override
public void run() {
while (!Thread.interrupted()) {
try {
//do some work
Thread.sleep(4000);
} catch (Exception e){
System.out.println("Exception occur" + e.getMessage());
e.printStackTrace();
}
}
}
}
Я пытаюсь запустить и остановить поток, когда получаю действие Intent от MainActivity.java. Я установил BroadcastReceiver для связи между сервисом и активностью. Я начинаю тему следующим образом. Поток начинается нормально, и я получаю тост.
public class MyReceiver extends BroadcastReceiver {
MyLocalThread thread = new MyLocalThread();
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals("com.example.START")) {
//starts the thread
thread.start();
Toast.makeText(context, "Service is started.", Toast.LENGTH_LONG).show();
} else if (action.equals("com.example.STOP")) {
//stops the thread
thread.interrupt();
Toast.makeText(context, "Service has stopped.", Toast.LENGTH_LONG).show();
}
}
}
Но при попытке остановить мой тред т.е.second action не работает. Я получаю сообщение TOAST о том, что служба остановлена, но мой поток продолжает работать. Это не прекращается. Я не знаю, что я делаю неправильно?
Я предполагаю, что у вас опечатка - метод запуска должен быть while (!Thread.interrupted). Также обратите внимание, что при использовании статического метода (в отличие от метода экземпляра isInterrupted) статус прерывания очищается при каждом вызове. (Не очищается на isInterrupted).
У вас также есть состояние гонки: start не обязательно происходит немедленно - это зависит от планировщика - поэтому теоретически вы можете пытаться остановить поток (прерывание) еще до его запуска и, таким образом, пропустить прерывание (поскольку оно не было запущено). т началось).




Обновлено:
Вы можете вызвать thread.interrupt(), чтобы прервать поток и поставить Thread.interrupted() проверку вместо создания логического значения.
class MyLocalThread extends Thread {
public void run() {
if (!Thread.interrupted()) {
try {
//do some work
}
catch (InterruptedException e) {
System.out.println("InterruptedException occur");
}
}
}
}
Прервать поток следующим образом:
MyLocalThread thread = new MyLocalThread();
thread.start();
// when need to stop the thread
thread.interrupt();
Это ничего не меняет - если бы run был ложным, он вышел бы из цикла while, достиг бы нижней части функции и автоматически вернулся.
Декс, спасибо за ваши усилия, я проверю это и вернусь к вам через минуту.
@cantona_7 cantona_7 Я обновил ответ. Это должно сработать. Но чтобы вы знали, мы ничего не можем сделать, чтобы остановить поток. мы можем только уведомить систему, чтобы прервать его.
Я только что обновил вопрос, если вы посмотрите, вы увидите мою реализацию.
На самом деле я это уже видел. и мой подход был основан на этом посте. Кажется, я где-то пропустил сюжет.
Эта функциональность встроена в Thread. Посмотрите на thread.interrupt и thread.isInterrupted. Нет причин переписывать эту функциональность.
привет, но я не использую прерывание (), верно? Я пытаюсь прекратить. Извините, если это глупый вопрос.
Interrupt() устанавливает флаг. isInterrupted() проверяет флаг. Это избавляет от необходимости использовать ваш рабочий флаг, и он будет реализован правильно.
Использование прерывания имеет то преимущество, что если поток ожидает, он будет разбужен InterruptedException, где вы можете предпринять действия, чтобы красиво завершить поток.
Что бы вы предложили мне сделать? Использовать прерывание() вместо завершения?
Что делает runnable в цикле while? Может быть, он спит или заблокирован, ожидая ввода?