Поддерживайте фоновую ветку, используя PARTIAL_WAKE_LOCK
Мне нужно периодически запускать задачу в фоновом режиме и не спать на процессоре. В соответствии с документацией Android я использовал PARTIAL_WAKE_LOCK для этой цели. Чтобы протестировать пробужденную блокировку, я написал Сервис, который запускает поток каждые 2 минуты, используя ScheduledThreadPoolExecutor. Этот поток просто записывает строку в файл журнала в SDCard.
Затем я выполнил следующий простой тест: запустите приложение и отключите устройство от источника питания. После 2 или 3 часов правильного выполнения служба перестает запускать поток, и в файле журнала не записываются новые строки.
Код услуги:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "Service onStartCommand");
PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WiOpp wakeLock");
wakeLock.acquire();
TestTask testTask = new TestTask(getApplicationContext());
ScheduledThreadPoolExecutor monitorPool = new ScheduledThreadPoolExecutor(1);
monitorPool.scheduleAtFixedRate(testTask, 0, 120, TimeUnit.SECONDS);
return START_STICKY;
}
Код TestTask:
@Override
public void run() {
//write on log file
LogManager.getInstance().logData("I am running!");
}
Я ожидаю, что поток также выполняется, когда дисплей выключен, но, глядя на мой файл журнала, кажется, что это не так. Где я не прав?
1 ответ
На Android 6.0+ режим Doze в основном отменяет ваш будильник. Устройства до 6.0 от некоторых производителей делают подобные вещи.
Можно ли избежать режима Doze?
Пользователь может добавить ваше приложение в белый список оптимизации батареи. Обратите внимание, что просить пользователей сделать это через ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
может привести к тому, что ваше приложение будет заблокировано в магазине Play Store, если это будет один из ваших каналов распространения.
Или пользователь может постоянно держать свое устройство на зарядном устройстве.
Если вы можете справиться с менее частым периодом голосования, вы можете попробовать setAndAllowWhileIdle()
или же setExactAndAllowWhileIdle()
с AlarmManager
, В лучшем случае вы будете получать контроль каждые 9 минут. Возможно, вы не имеете доступа к Интернету.
В противном случае подход на стороне устройства с опросом каждые N минут обречен.
Google хочет, чтобы вы использовали GCM/FCM и избегали опроса, заставляя ваш сервер передавать информацию, если и когда это необходимо. Я не знаю, относится ли это к вашему случаю использования.