2013-03-26 3 views
0

Нажатие кнопки Я вызываю следующую функцию.Проблема со сном в потоке

private void badButtonHandler() { 
    Camera.Parameters params = mCamera.getParameters(); 
    params.setColorEffect(Camera.Parameters.EFFECT_NEGATIVE); 
    mCamera.setParameters(params); 
    if(thread != null){ 
     thread = null; 
    } 
    thread = new Thread() 
    { 
     @Override 
     public void run() { 
      try { 
       while(true) { 
        sleep(5000); 
        Camera.Parameters params = mCamera.getParameters(); 
        params.setColorEffect(Camera.Parameters.EFFECT_NONE); 
        mCamera.setParameters(params); 
       } 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    }; 

    thread.start(); 
} 

Эта функция предназначена для изменения цветового эффекта камеры через 5 секунд после нажатия кнопки. При первом нажатии соответствующей кнопки она ведет себя так, как ожидалось. Но дополнительные вызовы этой функции ведут себя не так, как ожидалось. I.e., второй раз, когда он ждет 2 секунды, после чего он уменьшается до более низких значений с каждым щелчком.

+0

использовать флаг для управления потоками, потому что тема непрерывно работает после, когда и нажмите кнопку первый раз –

+0

В андроида я думаю, что вместо того, чтобы использовать тему его лучше использовать Handler с помощью метода postDelayed HTTP://developer.android.com/reference/android/os/Handler.html#postDelayed(java.lang.Runnable, long) –

+0

Могу ли я остановиться после запуска 1-го раза ?? и снова запустите .. –

ответ

0

Вы должны не полагаться на sleep() как точный таймер. Он не будет автоматически просыпаться в назначенное время и становится активным в настоящее время потоком, из-за простого факта, что все потоки находятся во власти планировщика потоков. Это, несомненно, будет варьироваться от ОС к ОС на основе данной JVM.

Я всегда полагался на пользовательские функции таймера для этих типов сценариев. Так, например:

myTimer(System.nanoTime()); 

public static void myTimer(long startTime) { 
    while (startTime + 5000000000 > System.nanoTime()) { //Wait for 5 seconds 
     try { 
      Thread.sleep(50); //Sleep at ~50 millisecond intervals 
     } 
     catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

Вам не нужно будет создать совершенно новую нить, как вы сделали в вашем примере, так как Thread.sleep() поместит текущий поток спать. Кроме того, использование цикла while (true) - это просто плохая практика программирования.

Использование nanoTime() является предпочтительным, поскольку это самый точный системный таймер, доступный на Java.

Дополнительную информацию о ненадежности функции sleep() см. В this documentation.

+0

Спящий режим можно упростить в Android с помощью ['SystemClock.sleep (long)'] (http: // developer.android.com/reference/android/os/SystemClock.html#sleep(long)), который не бросает 'InterruptedException' –

+0

@JustinMuller. Я бы никогда не отказался от возможности прерывания потока, если у меня не было явной причины Сделай так. Особенно, когда я хочу контролировать то, что происходит, когда конечный пользователь нажимает кнопку спящего режима на своем устройстве * n * секунд до истечения таймера. –

-1

попробовать это

Thread timer = new Thread(new Runnable() { 

     @Override 
     public void run() { 
      // TODO Auto-generated method stub 
      try { 
       Thread.sleep(3000); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      }finally{ 
       //Your desired work 
      } 
     } 
    }); 
    timer.start(); 
+0

Добавление предложения finally не учитывает тот факт, что sleep() никогда не будет использоваться в качестве таймера. –

Смежные вопросы