Сохранение фонового потока с помощью PARTIAL_WAKE_LOCK

Мне нужно периодически запускать задачу в фоновом режиме и не выключать процессор. Согласно документации для Android, я использовал PARTIAL_WAKE_LOCK для этой цели. Чтобы протестировать блокировку пробуждения, я написал службу, которая запускает поток каждые 2 минуты, используя ScheduledThreadPoolExecutor. Этот поток просто записывает строку в файл журнала на SD-карте.

Затем я выполнил следующий простой тест: запустил приложение и отключил устройство от питания. Через 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!");
}

Я ожидаю, что поток также выполняется, когда дисплей выключен, но, глядя на мой файл журнала, это не так. Где я не прав?


person Mattia Campana    schedule 14.12.2016    source источник
comment
На какой версии Android вы тестируете и на каком конкретном оборудовании? В Android 6.0 появился режим Doze, и у разных производителей есть свои агрессивные режимы энергосбережения, которые предшествовали Doze. Делать что-то каждые две минуты (используя ScheduledExecutorService, AlarmManager, JobScheduler и т. д.) на современных устройствах Android будет невозможно, если только пользователь не добавит ваше приложение в белый список оптимизации батареи.   -  person CommonsWare    schedule 15.12.2016
comment
Я использую Nexus 5 (Android 6.0.1) и Nexus 6 (Android 7). Можно ли избежать режима Doze?   -  person Mattia Campana    schedule 15.12.2016
comment
@CommonsWare Это относится и к рабочему потоку, созданному что-то вроде «new MyThread().start()»? Я читал руководство для разработчиков Android, но в нем говорится только о заданиях, связанных с AlarmManager и сетью. Он только что упомянул об «отсрочке фонового ЦП» один раз и не дал никакого объяснения этому.   -  person Jenix    schedule 20.06.2017
comment
@Jenix: Это относится и к чему-то вроде «new MyThread().start()»? -- да.   -  person CommonsWare    schedule 20.06.2017
comment
@CommonsWare Спасибо!! Ты спас меня.. Я никогда не думал, что это будет :(   -  person Jenix    schedule 20.06.2017


Ответы (1)


На Android 6.0+ режим дремоты в основном отменяет ваш вейклок. Устройства до версии 6.0 от некоторых производителей делают то же самое.

Можно ли избежать режима Doze?

Пользователь может добавить ваше приложение в белый список оптимизации батареи. Обратите внимание, что просьба к пользователям сделать это через ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS может привести к ваше приложение было заблокировано в Play Маркете, если это был один из ваших каналов распространения.

Или пользователь может постоянно держать свое устройство на зарядном устройстве.

Если вы можете обойтись менее частым периодом опроса, вы можете попробовать setAndAllowWhileIdle() или setExactAndAllowWhileIdle() с AlarmManager. В лучшем случае вы будете получать контроль каждые 9 минут. Однако у вас может не быть доступа к Интернету.

В противном случае метод опроса на стороне устройства каждые N минут обречен.

Google хочет, чтобы вы использовали GCM/FCM и избегали опроса, заставляя ваш сервер передавать информацию, когда и когда это необходимо. Я не знаю, имеет ли это отношение к вашему варианту использования.

person CommonsWare    schedule 14.12.2016
comment
Большое спасибо @CommonsWare. Да, эта информация очень полезна для моего случая. Моя цель - иметь возможность периодически выполнять в фоновом режиме обнаружение одноранговых узлов P2P, чтобы находить новые устройства поблизости. С помощью AlarmManager (каждые 9 минут) можно ли использовать инфраструктуру WifiP2P? - person Mattia Campana; 15.12.2016
comment
@MattiaCampana: я не играл с WifiP2P. Однако, если вы также не держите WifiLock, я ожидаю, что WiFi будет недоступен во время дремоты, и я понятия не имею, достаточно ли WifiLock, чтобы он оставался включенным во время дремоты. Насколько я знаю, взаимодействие между WifiLock и Doze не задокументировано. - person CommonsWare; 15.12.2016
comment
@CommonsWare о, еще кое-что! Все еще не уверены в WifiLock? - person Jenix; 20.06.2017
comment
Это(developer.android.com/guide/topics/media/mediaplayer.html) не упоминает конкретно о Doze, но предлагает использовать WifiLock для потоковой передачи, поэтому я думаю, что WifiLock достаточно. Как вы думаете? - person Jenix; 20.06.2017
comment
@Jenix: Все еще не уверены в WifiLock? -- правильный. Я не играл с этим сценарием. Как вы думаете? -- Я бы сказал, что WifiLock, вероятно, необходимо. Насколько это достаточно — это другой вопрос, и этого я не знаю, извините. - person CommonsWare; 20.06.2017
comment
Спасибо за честный ответ :) - person Jenix; 20.06.2017
comment
Ты прав! Я имею в виду, недостаточно! Я просто вспомнил, что читал в чьем-то посте несколько дней назад. Он попробовал WifiLock, но ему нужно было настроить белый список в меню «Настройки» > «Аккумулятор» > «Оптимизация аккумулятора». - person Jenix; 20.06.2017