Поддерживайте фоновую ветку, используя 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 и избегали опроса, заставляя ваш сервер передавать информацию, если и когда это необходимо. Я не знаю, относится ли это к вашему случаю использования.

Другие вопросы по тегам