2016-01-27 1 views
1

Мой отредактированный код. Этот интервал - это вектор, в котором хранятся требуемые задержки, а индекс инициализируется значением 0. Я получил свою ошибку. Это то, что у меня есть.Нужно реализовать таймер (с характером переменных временных интервалов) в приложении для Android.

public class MainActivity{ 
private int index; 
     //Some code and initializations 

    public void startTimer{ 
    index=0; 
    private Timer timer=new Timer(); 
    private TimerTask timertask=new MyTimerTask(); 
    // timer.schedule(timertask,0,1000);   //This line was causing trouble 

    } 

    private class MyTimerTask extends TimerTask 
     { 
       public void run() {  

      handler.postDelayed(new Runnable() { 

     int limit = interval.size(); 

     @Override 
     public void run() { 
      if (index < limit) { 
       Integer secondDelay = interval.get(k); 
       Log.e(TAG, "index= " + index + " interval= " + secondDelay + " seconds"); 

       //Some code 

       long delay = secondDelay * 1000; 
       index++; 
       handler.postDelayed(this, delay); 
      } else { 
       handler.removeCallbacksAndMessages(null); //Cancelling the handler.postDelayed 
       Log.e(TAG, "Cancelling timer"); 
       timer.cancel(); 
      } 
     } 
    }, 0); 
    } 
} 
} 

Выход в журнал осуществляется через каждые 1 секунду.

Прокомментированная строка вызывает ошибку. Должно быть timer.schedule (timertask, 0); и теперь он работает правильно.

+0

Подождите, вы немного запутался, индекс и к не объявлены, и вам не нужно удалитьCallBacks e .... timer.cancel! ??! Пожалуйста, начните с кода моего ответа – appersiano

+0

Я узнал об ошибке и исправил ее. Спасибо, вы очень помогли –

ответ

0

Забудьте Timer: было бы проще всего сделать это с помощью сна в цикле:

class MyTimerRunnable implements Runnable { 
    @Override public void run() { 
    for (int i = 1; i < 5; ++i) { 
     try { 
     Thread.sleep(/* for however long */); 
     } catch (InterruptedException e) { 
     Thread.currentThread().interrupt(); 
     throw new RuntimeException(e); 
     } 
     System.out.println("Current:"+new Date()); 
    } 
    } 
} 

, а затем просто начать это в своей собственной Thread (например new Thread(new MyTimerRunnable()).start();), или путем подачи его на Executor.

0

Я создал собственный собственный класс таймера, используя класс Handler (тот, который находится в пакете android.os). Вот основная идея этого.

Ваш класс содержит поле типа Handler. Вы создаете экземпляр в конструкторе. Вы также должны иметь поле под названием interval.

В конструкторе, после создания объекта обработчика, вы вызываете postDelayed на обработчике. Для этого метода требуется два параметра. Первый - это Runnable, а второй - задержка в ms.

Чтобы записать работоспособный объект, не забудьте повторно вызвать обработчика с точно такими же параметрами после того, как вы сделали то, что хотели.

И для второго параметра просто перейдите в поле interval.

tl; dr: Вы видите, что я здесь делаю? Когда таймер построен, вы отправляете событие, которое произойдет через некоторое время. Когда это событие произошло, сделайте то, что вам нравится, и опубликуйте другое событие, которое произойдет через одно и то же время.

Чтобы изменить интервал, просто добавьте установщик, чтобы установить объект interval. И в следующий раз, когда runnable будет запущен, он отправит событие, которое будет запущено после нового интервала!

Вот код для моего класса таймера:

import android.os.Handler; 

public class Timer { 
    private Handler handler; 
    private boolean paused; 

    private int interval; 

    private Runnable task = new Runnable() { 
     @Override 
     public void run() { 
      if (!paused) { 
       runnable.run(); 
       Timer.this.handler.postDelayed (this, interval); 
      } 
     } 
    }; 

    private Runnable runnable; 

    public int getInterval() { 
     return interval; 
    } 

    public void setInterval(int interval) { 
     this.interval = interval; 
    } 

    public void startTimer() { 
     paused = false; 
     handler.postDelayed (task, interval); 
    } 

    public void stopTimer() { 
     paused = true; 
    } 

    public Timer (Runnable runnable, int interval, boolean started) { 
     handler = new Handler(); 
     this.runnable = runnable; 
     this.interval = interval; 
     if (started) 
      startTimer(); 
    } 
} 

EDIT: после рассмотрения вашего вопроса, похоже, что вы не используете Android, но вы помечены на вопрос андроиде. В любом случае, если вы на самом деле нет, просто используйте javax.swing.Timer, что лучше. Ищите документы в Google!

+0

название сообщения говорит «андроид», поэтому кажется, что пользователь использует андроид, но он не знает, существование класса Handler, во всяком случае отличный класс! – appersiano

1

У меня была аналогичная проблема, и я решил с Handler

final Handler handler = new Handler(); 
     handler.postDelayed(new Runnable() { 
      int minute = 0; 
      @Override 
      public void run() { 
       { 
        Log.d("TAG", "next run after "+minute+" minutes"); 
        long delay = minute * 60000; 
        minute++; 
        handler.postDelayed(this,delay); 
       } 
      } 
     }, 0); 

И это logcat

01-27 11:49:55.830 23761-23761/? D/TAG: next run after 0 minutes 
01-27 11:49:55.945 23761-23761/? D/TAG: next run after 1 minutes 
01-27 11:50:56.015 23761-23761/? D/TAG: next run after 2 minutes 
01-27 11:52:56.115 23761-23761/? D/TAG: next run after 3 minutes 
01-27 11:55:56.225 23761-23761/? D/TAG: next run after 4 minutes 
...and so on 

Мой пример имеет минутный интервал, но вы можете легко адаптировать его к секундам.

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


EDIT Я изменил пример на основе ваших комментариев

final ArrayList<Integer> interval = new ArrayList<>(); 
interval.add(1); 
interval.add(5); 
interval.add(10); 
interval.add(3); 

final Handler handler = new Handler(); 
handler.postDelayed(new Runnable() { 
    int index = 0; 

    @Override 
    public void run() { 
     { 

      if (index < interval.size()) { 
       Integer secondDelay = interval.get(index); 

       Log.d("TAG", "next run after " + secondDelay + " seconds"); 
       long delay = secondDelay * 1000; 
       index++; 
       handler.postDelayed(this, delay); 
      } else { 
       Log.d("TAG", "I finish"); 
      } 

     } 
    } 
}, 0); 

LogCat:

01-27 17:51:09.940 28113-28113/? D/TAG: next run after 1 seconds 
01-27 17:51:10.940 28113-28113/? D/TAG: next run after 5 seconds 
01-27 17:51:15.950 28113-28113/? D/TAG: next run after 10 seconds 
01-27 17:51:25.960 28113-28113/? D/TAG: next run after 3 seconds 
01-27 17:51:28.965 28113-28113/? D/TAG: I finish 
+0

Значит, вы имеете в виду «задержку» в handler.postDelayed должен содержать переменный временной интервал? –

+0

Да, и он автоматически увеличивает каждый элемент, анонимный runnable называется – appersiano

+0

По вашему предложению, я использую delay = interval.get (k) * 1000; handler.postDelayed (это, задержка); где интервал - это вектор, состоящий из переменных задержек, а k - индекс, но если я использую это, то вывод всегда отличается на 1 секунду независимо от значения в интервале [k] –

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