Я работаю над приложением, которое требует, чтобы оно подключалось к сети каждые x минут и проверяло наличие новых данных. Чтобы предотвратить интенсивное использование сети и данных, задача должна выполняться с фиксированной скоростью, но какой подход лучше всего использовать для такого решения? Объект Handler
или Timer
?
Обработчик или таймер для планирования задач с фиксированной скоростью
Ответы (6)
Есть некоторые недостатки использования таймера
- Он создает только один поток для выполнения задач, и если задача выполняется слишком долго, другие задачи страдают.
- Он не обрабатывает исключения, создаваемые задачами, и поток просто завершается, что влияет на другие запланированные задачи, и они никогда не запускаются.
Принимая во внимание, что, с другой стороны, ScheduledThreadPoolExecutor
правильно решает все эти проблемы, и нет смысла использовать Timer. Есть два метода, которые могут быть полезны в вашем случае.
расписание по фиксированной скорости (...)
расписание с фиксированной задержкой (..)
class LongRunningTask implements Runnable { @Override public void run() { System.out.println("Hello world"); } } ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1); long period = 100; // the period between successive executions exec.scheduleAtFixedRate(new LongRunningTask (), 0, duration, TimeUnit.MICROSECONDS); long delay = 100; //the delay between the termination of one execution and the commencement of the next exec.scheduleWithFixedDelay(new MyTask(), 0, duration, TimeUnit.MICROSECONDS);
И для отмены исполнителя используйте это - ScheduledFuture
// schedule long running task in 2 minutes:
ScheduledFuture scheduleFuture = exec.scheduleAtFixedRate(new MyTask(), 0, duration, TimeUnit.MICROSECONDS);
... ...
// At some point in the future, if you want to cancel scheduled task:
scheduleFuture.cancel(true);
Вы должны использовать Сервис и AlarmReceiver Like This Вот для чего они нужны. Если вы используете таймер или любой другой механизм в своей деятельности и настроили свои данные для обновления каждые «несколько минут», есть большая вероятность, что пользователь не будет в вашем приложении, и Android вполне может очистить его, оставив ваше приложение * не обновление. Будильник будет работать до тех пор, пока устройство не будет выключено.
если вы ищете хорошую производительность и меньшее потребление батареи, вам следует подумать о Alarm manager
, интегрированном с broadcast Reciever
, который будет вызывать службу через время X и позволять ей выполнять работу, а затем снова отключать ее.
Однако при использовании timer
или handler
вам нужно, чтобы ваша служба всегда работала в фоновом режиме. если вы не хотите, чтобы он получал данные во время работы приложения, поэтому вам не нужна служба.
если вы выбираете handler
или timer
, используйте таймер, потому что он проще и может выполнять работу с большей производительностью. handlers
обычно используется для обновления пользовательского интерфейса с помощью Runnable
или Messeges
.
Может быть диспетчер тревог, таймер, обработчик или ScheduledThreadPoolExecutor.
Взгляните на это:
Планирование повторяющейся задачи в Android
Это зависит от того, будут ли обновления происходить, пока пользователь не находится в приложении (будут ли проверки останавливаться, как только пользователь уйдет, чтобы отправить SMS, например, или должен продолжаться опрос?) может ли проверка выполняться в потоке пользовательского интерфейса, а затем порождаться загрузка из службы или AsyncTask или другого потока? Может быть, все это не имеет значения...
Если вам не нужно ничего обновлять, пока пользователь не просматривает приложение, используйте таймер. Обслуживание было бы излишеством. Вот пример кода для достижения этого:
final Runnable updateRunnable = new Runnable() {
public void run() {
// Fetch the date here in an async task
}
};
final Handler myHandler = new Handler();
private Timer myTimer;
private void updateUI() {
myHandler.post(updateRunnable);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ... other things here
myTimer = new Timer();
myTimer.schedule(new TimerTask() {
@Override
public void run() {
updateUI(); // Here you can update the UI as well
}
}, 0, 10000); // 10000 is in miliseconds, this executes every 10 seconds
// ... more other things here
}
Менеджер тревог или обработчик. Если вы используете обработчик и postDelayed, ваш процесс не должен оставаться активным все время.
На самом деле официально рекомендуется использовать Handler вместо Timer или TimerTask: http://android-developers.blogspot.ru/2007/11/stitch-in-time.html