Как вы думаете, Thead.sleep () — хороший подход в обслуживании?

#android #multithreading #service #handle

#Android #многопоточность #Обслуживание #обрабатывать

Вопрос:

У меня есть сервис как MyService . В моем сервисе у меня есть глобальная переменная: value которая управляется функцией control_Value() . Функция, используемая для управления значением varialbe value , следующим образом управляет:

Время при вызове функции называется начальным временем. В начальный момент времени значение устанавливается как One . Через 3 секунды после начального времени значение устанавливается равным Zero . Значение будет сохраняться Zero до тех пор, пока функция не будет вызвана снова.

Основываясь на приведенном выше правиле, я написал control_Value() следующим образом:

 public void control_Value()(){
   value="One";
   try{
       Thread.sleep(3000);
       value="Zero";
   }
   catch{}
}
  

Как вы думаете, Thead.sleep (3000) — хороший подход? Если нет, пожалуйста, дайте мне лучшее решение. Обратите внимание, что вышеупомянутая функция работала хорошо.

Это мой сервис

 public class MyService extends Service {
  String value=null;
  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
          //TODO do something useful

          return Service.START_NOT_STICKY;
  }

  @Override
  public IBinder onBind(Intent intent) {
        //TODO for communication return IBinder implementation
    return null;
  }
  @Subscribe
  public void onSMSContentReceived(OnSMSReceiverEvent event) {
      control_Value();
  }
}
  

Обновление: onSMSContentReceived вызывается автоматически, когда на телефон приходит SMS.

Это решение с использованием таймера обратного отсчета по предложению TGMCians

 //Global variable
private CountDownTimer mCountDownTimer;
//
 @Override
protected void onDestroy() {
    if(mCountDownTimer!=null){
            mCountDownTimer.cancel();
        }
    super.onDestroy();
}  
public void control_Value()(){

    mCountDownTimer = new CountDownTimer(3000,1000) {
    @Override
    public void onTick(long millisUntilFinished) {
        value="One";
    }
    @Override
    public void onFinish() {
        // Your stuff
        value="Zero";
    }
  };
  mCountDownTimer.start();
}
  

Комментарии:

1. «Как вы думаете, Thead. sleep(3000) — хороший подход?» Нет. В этом случае вы блокируете основной поток. AFAIK, вы получите ANR, если будете спать дольше 5 секунд.

2. Спасибо Onik. Каково ваше предложение? Вышеупомянутая функция используется в следующем сценарии: «когда вызывается функция. value Произойдет One в течение 3 секунд, после чего value будет сброшен на Zero »

3. Это зависит от того, onStartCommand() может ли возврат до value = 0 или нет. Если value можно изменять асинхронно, то, возможно, IntentService подойдет. Если нет, я думаю, цикла проверки разницы между начальным и текущим временем было бы достаточно. Или используйте механизмы синхронизации Java.

4. Для упрощения я просто вызываю функцию controlValue() в onStartCommand() моем примере. В реальном случае я вызываю функцию в BroacastReceiver SMS. Следовательно, я думаю, что он будет независимым с возвращаемым значением onStartCommand() . Исходя из этого, я думаю, что второе решение может быть хорошим. Правильно ли это?

5. Я обновил его, чтобы сделать это в реальном случае. Вам не нужно рассматривать onStartCommand() функцию

Ответ №1:

Как вы думаете, Thead.sleep (3000) — хороший подход?

Никогда. Служба запускается в главном потоке приложения без пользовательского интерфейса. Приложение выдаст сообщение ANR, если вы удерживаете основной поток приложения в течение определенных секунд.

Что делать

Если вы хотите выполнить операцию через определенные секунды, то вы можете использовать CountDownTimer в своем сервисе методы, в которых есть onTick amp; onFinish , где onTick выполняется регулярное нажатие и onFinish выполняется по истечении времени.

Комментарии:

1. Спасибо. Я обновил свой вопрос 1 минуту назад. Не могли бы вы это проверить? Я переношу controValue() функцию в другую функцию, которая вызывается, когда трансляция принимается в виде SMS

2. Это также нормально, если ваша служба работает до onSMSContentReceived вызова.

3. Спасибо. Я посмотрел на метод таймера обратного отсчета. Это выглядело хорошо. Но я сожалею об отмене и инициализации этого. Например, если я использую его в controlValue функции, он отображает таймер отключения вызова всякий раз, когда controlValue вызывается. Например, у меня есть три входящих SMS, затем он вызовет controlValue три раза без отмены. (Потому что я думаю, что cancel — это вызов в onDestroy ())

4. onFinish будет вызван один раз через X секунд, там вам нужно вызвать controlValue

5. кажется, все в порядке, продолжайте!