2014-02-12 6 views
5

Я хотел бы начать повторять две строки кода каждые 5 секунд, когда я нажимаю кнопку START и заканчиваю ее, когда нажимаю кнопку STOP. Я старался использовать TimerTask и Handles, но не мог понять, как это сделать.Android - петля часть кода каждые 5 секунд

public class MainActivity extends Activity { 




    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 


      //final int i; 
      final TextView textView = (TextView) findViewById(R.id.textView); 
      final Button START_STOP = (Button) findViewById(R.id.START_STOP); 
      final ImageView random_note = (ImageView) findViewById(R.id.random_note); 
      final int min = 0; 
      final int max = 2; 
      final Integer[] image = { R.drawable.a0, R.drawable.a1,R.drawable.a2 }; 



     START_STOP.setTag(1); 
     START_STOP.setText("START"); 


     START_STOP.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
      int status = (Integer) v.getTag(); 
      if (status ==1) { 
       textView.setText("Hello"); 
       START_STOP.setText("STOP"); 
       v.setTag(0); 

       final Random random = new Random(); 

           //************************************************************ 
       // I would like to loop next 2 lines of code every 5 seconds.// 

           int i = random.nextInt(2 - 0 + 1) + 0; 
       random_note.setImageResource(image[i]); 

       //************************************************************ 
        } 

      else 
      { 
       textView.setText("Bye"); 
       START_STOP.setText("Let's PLAY!"); 
       v.setTag(1); 
      } 


      } 
     });  

    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.main, menu); 
     return true; 
    } 


} 
+1

Что не работает с TimerTask? –

+0

Не знаю. Когда я попытался запустить его на эмуляторе, он разбился. Но, вероятно, я сделал что-то не так, так как я начинающий Android (Java). – Damijan

ответ

18

Использование CountDownTimer, как в одном из других ответов, является одним из способов сделать это. Еще бы использовать обработчик и postDelayed метод:

private boolean started = false; 
private Handler handler = new Handler(); 

private Runnable runnable = new Runnable() {   
    @Override 
    public void run() { 
     final Random random = new Random(); 
     int i = random.nextInt(2 - 0 + 1) + 0; 
     random_note.setImageResource(image[i]); 
     if(started) { 
      start(); 
     } 
    } 
}; 

public void stop() { 
    started = false; 
    handler.removeCallbacks(runnable); 
} 

public void start() { 
    started = true; 
    handler.postDelayed(runnable, 2000);   
} 

Вот пример использования таймера и TimerTask:

private Timer timer; 
private TimerTask timerTask = new TimerTask() { 

    @Override 
    public void run() { 
     final Random random = new Random(); 
     int i = random.nextInt(2 - 0 + 1) + 0; 
     random_note.setImageResource(image[i]); 
    } 
}; 

public void start() { 
    if(timer != null) { 
     return; 
    } 
    timer = new Timer(); 
    timer.scheduleAtFixedRate(timerTask, 0, 2000); 
} 

public void stop() { 
    timer.cancel(); 
    timer = null; 
} 
+1

Я всегда использовал CountDownTimer в своих приложениях, например, каждые 5 секунд меняю баннеры на активность. Каков наилучший способ повторить действие каждые 5 секунд, CountDownTimer или Handler и postDelayed? – Giacomoni

+0

Спасибо. Где бы вы поместили это в мой оригинальный код? – Damijan

+2

Хороший вопрос giacomoni! Я посмотрел на CountDownTimer, и он использует обработчик внутри себя: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.0_r1/android/os/CountDownTimer .java # 109, поэтому я думаю, что они более или менее эквивалентны. Таймер использует TimerThread с очередью TimerTasks: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Timer.java#460 Это сложно чтобы сказать, какой из них лучше. Я не знаю достаточно о различиях между потоками и обработчиками, чтобы дать вам достаточно хороший ответ. – britzl

12

Вы можете использовать CountDownTimer как следующий метод:

private CountDownTimer timer; 

timer = new CountDownTimer(5000, 20) { 

    @Override 
    public void onTick(long millisUntilFinished) { 

    } 

    @Override 
    public void onFinish() { 
     try{ 
      yourMethod(); 
     }catch(Exception e){ 
      Log.e("Error", "Error: " + e.toString()); 
     } 
    } 
}.start(); 

И затем вызвать таймер снова:

public void yourMethod(){ 
    //do what you want 
    timer.start(); 
} 

Для отмены таймера, вы можете вызвать timer.cancel();

Надеюсь, это поможет!

+0

привет, сэр, может ли приведенный выше код использоваться для обновления активности, пока пользователь не нажмет кнопку ...? –

0

я не имею намного больше, чтобы добавить, кроме как отметить различия между использованием Handler, CountDownTimer и регулярным таймером. Как упоминалось выше, CountDownTimer использует обработчик внутри себя, поэтому это эквивалентно использованию обработчика напрямую. Обработчик используется для запуска файлов Ui в течение очень коротких периодов времени. Примером может быть setText для текстового представления. Для вычислительно-интенсивных задач обработчики могут вызвать задержку. Таймер также может выполнять только короткие задачи, но это не обязательно только для содержимого пользовательского интерфейса. Для более сложных задач следует использовать новый поток.

2

Вы можете использовать RxJava2/RxAndroid2 и создать Observable, который излучает сообщение каждую секунду (или что вы хотите), например, с псевдокоде:

Disposable timer = Observable.interval(1000L, TimeUnit.MILLISECONDS) 
      .timeInterval() 
      .subscribeOn(Schedulers.io()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(new Consumer<Timed<Long>>() { 
       @Override 
       public void accept(@NonNull Timed<Long> longTimed) throws Exception {    
        //your code here. 
        Log.d(TAG, new DateTime()); 
       } 
      }); 

Если вы хотите, чтобы остановить его, вы можете просто позвонить :

timer.dispose(); 

Этот код является более читаемым, чем другие.