По мнению многих разработчиков, в большинстве случаев к слишком быстрому разряду аккумуляторов смартфонов приводит плохая оптимизация приложений. В мае этого года в Google прошла очередная ежегодная конференция Google I/O, на которой было анонсировано много всего интересного для разработчиков. В частности, когда речь зашла об Android M, то одной из центральных тем были именно производительность мобильных устройств и продолжительность работы от аккумулятора. Давайте взглянем на новые функции и инструменты, которые помогут пользователям и разработчикам выжать ещё больше из аккумуляторов мобильных устройств.

Doze


Это один из главных инструментов в новой ОС для обуздания активности приложений, когда устройство находится в спящем режиме. На смартфонах под управлением Lollipop и более старых версий Android, любое приложение может вывести устройство из сна ради своего обновления, что позволяет поддерживать актуальность данных. Doze анализирует текущее состояние устройства и данные с акселерометра, определяет, когда смартфон не используется, и отправляет его в «глубокий сон». В этом режиме обновление приложений запрещается до тех пор, пока устройство не будет разбужено каким-то иным, более приоритетным событием. В режиме «глубокого сна» отключается сетевая активность, блокировки засыпания, предупреждения и задачи JobScheduler.

Как подсказывает опыт, часто обновляющиеся в фоновом режиме приложения являются одной из главных причин быстрого разряда аккумулятора. И Google придерживается того же мнения. На конференции была приведена информация, что планшеты Nexus 9 с запущенным Doze работали почти в два раза дольше в режиме ожидания.

Чтобы протестировать эту функцию, обновитесь до Android M, а затем с помощью команды ADB отключите зарядку устройства:

adb shell dumpsys battery unplug

Doze может переводить устройство в один из нескольких режимов:

  • ACTIVE: дисплей включен.
  • INACTIVE: дисплей выключен, но устройство активно.
  • IDLE_PENDING: переход в состояние «глубокого сна».
  • IDLE: устройство спит.
  • IDLE_MAINTENANCE: короткий промежуток времени, в течение которого разрешается выполнение всех запланированных уведомлений и обновлений.

Между этими состояниями можно переключаться вручную:

adb shell dumpsys deviceidle step

Сколько времени нужно на перевод устройства в этот режим?

adb shell dumpsys deviceidle

Это позволяет получить много интересной информации о Doze. К примеру, на Nexus 6 (с включённым дисплеем) были получены следующие результаты:

Whitelist system apps:
com.android.providers.downloads
com.android.vending
com.google.android.gms
Whitelist user apps:
com.facebook.katana
Whitelist app uids:
UID=10012: true
UID=10016: true
UID=10026: true
UID=10100: true
mSigMotionSensor={Sensor name="Invensense Significant Motion Detector", vendor="Invensense Inc.", version=1, type=17, maxRange=1.0, resolution=1.0, power=0.3, minDelay=-1}
mCurDisplay=Display id 0: DisplayInfo{"Built-in Screen", uniqueId "local:0", app 1440 x 2392, real 1440 x 2560, largest app 2413 x 2308, smallest app 1440 x 1356, mode 1, defaultMode 1, modes [{id=1, width=1440, height=2560, fps=60.0}], rotation 0, density 560 (494.27 x 492.606) dpi, layerStack 0, appVsyncOff 7500000, presDeadline 12666667, type BUILT_IN, state ON, FLAG_SECURE, FLAG_SUPPORTS_PROTECTED_BUFFERS}, DisplayMetrics{density=3.5, width=1440, height=2392, scaledDensity=3.5, xdpi=494.27, ydpi=492.606}, isValid=true
mIdleDisabled=false
mScreenOn=true
mCharging=false
mSigMotionActive=false
mState=ACTIVE
mInactiveTimeout=+30m0s0ms

В первой части перечисляются процессы, аккредитованные Doze. Их активность никак не ограничивается. Обратите внимание, что в этот список вручную добавлен Facebook (Настройки —> Аккумулятор —> Facebook —> активировать «Отключить оптимизацию»). Далее идёт раздел с информацией с акселерометра и состоянием дисплея. Эти данные будут использоваться для последующего вывода устройства из состояния «глубокого сна». В данном примере дисплей включен, а значит Doze находится в режиме ACTIVE.

Период неактивности устройства установлен в 30 минут. Если выключить дисплей, этот раздел меняется:

mState=INACTIVE
mInactiveTimeout=+30m0s0ms
mNextAlarmTime=+28m26s193ms

С выключенным дисплеем устройство переходит в режим INACTIVE и может переключиться в режим перехода в «глубокий сон». Таймаут также равен 30 минутам, и, согласно таймеру, из этого периода прошло около 1,5 минут. Вручную переводим устройство в IDLE_PENDING:

mState=IDLE_PENDING
mInactiveTimeout=+30m0s0ms
mNextAlarmTime=+24m34s189ms
mNextIdlePendingDelay=+5m0s0ms
mNextIdleDelay=+60m0s0ms

Спустя 30 минут пребывания в этом режиме, устройство перейдёт в IDLE. Таким образом, для перехода в «глубокий сон» требуется суммарно 60 минут. Переход:

mState=IDLE
mInactiveTimeout=+30m0s0ms
mNextAlarmTime=+59m42s953ms
mNextIdlePendingDelay=+5m0s0ms
mNextIdleDelay=+2h0m0s0ms

Через 60 минут сработает триггер, устройство пробудится и отправит все накопившиеся сообщения, инициализирует события и триггеры. Параметр mNextIdleDelay говорит о том, что следующее пробуждение из «глубокого сна» произойдёт через 2 часа. Получается следующая цикличность смен режимов: 1, 2, 4 и 6 часов. То есть самый большой промежуток между пробуждениями составляет 6 часов, 4 раза в сутки.

Как ведут себя приложения, когда устройство выходит из режима «глубокого сна»?

Можете самостоятельно протестировать своё приложение, отправив устройство в «глубокий сон»:

adb shell am set-idle <packageName> true

С помощью той же команды его можно пробудить (введя значение false вместо true), и посмотреть, как активируются разные процессы, рассылаются и выполняются запросы.

Как видите, Doze является замечательным инструментом для экономии аккумулятора, когда устройство выключено.

Режим ожидания для приложений


В текущих версиях Android любое приложение имеет доступ к радиомодулю, даже в фоновом режиме. Иными словами, какое-нибудь давно скачанное и забытое вами приложение может втихую по несколько раз в день передавать какие-либо данные без вашего ведома. С помощью Doze это можно заблокировать запуск приложений, но они всё-равно смогут запускать процессы и обновляться, когда пользователь включает дисплей устройства. С помощью новой функции режима ожидания для приложений (App standby) можно приложениям, которые не запускались в активном режиме в течение какого-то периода времени (в днях), принудительно назначать режим ожидания. В этом режиме приложениям ограничивается доступ в интернет или запуск каких-либо процессов, пока смартфон не будет подключён к зарядному устройству. Тем самым экономится аккумулятор устройства.

Как работает режим ожидания для приложений? Если выполнить:

adb shell dumpsys usagestats

то можно получить много информации об активности приложений за последний день/неделю/месяц и год.

Например
user=0
In-memory daily stats
timeRange="6/1/2015, 5:00 - 11:16 PM"
   packages
     package=com.google.android.googlequicksearchbox totalTime="00:36" lastTime="6/1/2015, 10:56 PM" inactiveTime="01:05"
     package=com.android.providers.calendar totalTime="00:00" lastTime="6/1/2015, 10:20 PM" inactiveTime="02:26"
     package=com.android.providers.media totalTime="00:00" lastTime="6/1/2015, 10:20 PM" inactiveTime="02:20"
     package=com.android.providers.downloads totalTime="00:00" lastTime="6/1/2015, 10:20 PM" inactiveTime="02:20"
     package=com.android.defcontainer totalTime="00:00" lastTime="6/1/2015, 11:10 PM" inactiveTime="00:00"
     package=android totalTime="00:00" lastTime="6/1/2015, 10:32 PM" inactiveTime="01:44"
     package=com.urbandroid.inline totalTime="00:00" lastTime="6/1/2015, 11:14 PM" inactiveTime="00:00"
     package=com.google.android.gm totalTime="00:00" lastTime="6/1/2015, 9:01 PM" inactiveTime="06:36"
<snip>
In-memory weekly stats
timeRange="5/29/2015, 2:33 PM - 6/1/2015, 11:16 PM"
   packages
     package=com.amazon.mShop.android.shopping totalTime="01:04" lastTime="5/29/2015, 3:24 PM" inactiveTime="3:55:51"
     package=com.google.android.youtube totalTime="55:51" lastTime="5/31/2015, 2:04 AM" inactiveTime="1:09:00"
     package=com.android.providers.telephony totalTime="00:00" lastTime="5/29/2015, 2:56 PM" inactiveTime="5:37:10"
     package=com.android.sdm.plugins.connmo totalTime="00:00" lastTime="5/29/2015, 3:13 PM" inactiveTime="5:46:30"
     package=com.google.android.googlequicksearchbox totalTime="33:12" lastTime="6/1/2015, 10:56 PM" inactiveTime="01:05"
     package=com.android.providers.calendar totalTime="00:00" lastTime="6/1/2015, 10:20 PM" inactiveTime="02:26"
     package=com.android.providers.media totalTime="00:00" lastTime="6/1/2015, 10:20 PM" inactiveTime="02:20"
     package=com.google.android.apps.docs.editors.docs totalTime="00:00" lastTime="5/29/2015, 3:13 PM" inactiveTime="5:46:30"
     package=com.google.android.onetimeinitializer totalTime="00:00" lastTime="5/29/2015, 3:13 PM" inactiveTime="5:46:30"

Встроенный в ОС алгоритм определяет дату последнего запуска приложения, и при необходимости переводит его в неактивный режим. Список таких приложений можно просмотреть, если зайти в меню настроек в пункт “Inactive apps”.



Производительность приложений


Наверное, все из вас оказывались в ситуации, когда аккумулятор смартфона садится слишком быстро, но непонятно, из-за чего это происходит. Если зайти в Настройки —> Батарея, то можно получить подробную статистику потребления энергии по каждому приложению:



В данном случае основные потребители заряда аккумулятора: ЦПУ (в том числе и в фоновом режиме), сетевой протокол и радиомодуль. Представленная статистика собрана за 28 часов, с момента полной зарядки аккумулятора.
Также в Android M теперь доступно меню, с помощью которого можно «игнорировать оптимизацию». В этом случае отключаются Doze и режим ожидания для приложений. Это позволяет разработчикам тестировать производительность своих приложений как с включённой, так и с выключенной оптимизацией, выясняя, как это влияет на продолжительность работы от аккумулятора. А заодно как быстро устаревают данные в приложении.

GCM Network Manager


Замечательная новинка, для использования которой даже не требуется наличие Android M — её можно запускать на любых версиях ОС, вплоть до 2.3!

В вышедшем в конце прошлого года Lollipop появился JobScheduler API. На Android 5.0 и выше этот API отделяет от приложений все аппаратные предупреждения и блокировки засыпания, перенося их на уровень ОС. Это позволяет операционной системе агрегировать все эти события от разных приложений, тем самым уменьшая количество пробуждений и предупреждений, а значит и экономя заряд аккумулятора. Замечательно, вот только работает это на Lollipop и выше (на момент написания статьи, это примерно 12,4% Android-устройств).

Чтобы обеспечить тот же уровень производительности для сетевых соединений, в Google Play Services версии 7.5 добавят GCM Network Manager. Он использует фреймворк, аналогичный JobScheduler, но при этом будет работать на любых устройствах, где установлен Google Play Services (вплоть до Android 2.3, то есть на 99% всех Android-устройств). GCM Network Manager поддерживает такие же сценарии и режимы, что и JobScheduler, а также позволяет ограничивать количество сетевых подключений до тех пор, пока смартфон не будет подключён к зарядному устройству, а также использовать для больших обновлений исключительно Wi-Fi.

* * *

Все эти нововведения говорят о том, что Google озаботился производительностью приложений и старается дать разработчикам подходящие инструменты. Также мы теперь можем лучше контролировать поведение приложений ради снижения энергопотребления смартфонов.

Комментарии (14)


  1. Revertis
    03.08.2015 18:22
    +3

    GCM Network Manager еще один пример того, как Гугл перетягивает часть функций системы в свой фреймворк, тем самым усложняя вендорам и разработчикам уход от себя. Не нравится Гуглу свобода Андроида.


    1. livotov
      04.08.2015 09:13
      +2

      Это как раз наоборот попытка решения проблемы фрагментации, так как если бы все эти функции оставались внутри системы, то с текущим положением дел, когда сторонние вендоры просто забивают на поддержку и в лучшем случае выпускают новую версию системы через пол года-год после выхода официального релиза от гугл, эти функции были бы мало кому доступны. Собственно, это основная идея google play services, которые ставятся с маркета на широкий спектр версий ОС и оперативно обновляются там же, вне зависимости от того, когда почешется вендор.


      1. Revertis
        04.08.2015 09:24
        -2

        Гугл очень хочет, чтобы вы именно так и думали.


        1. Poytu
          04.08.2015 10:26

          Гугл заявлял, что так и сделает (в итоге) еще со времен 2.1.
          Услышав это годы назад я дико был рад. Даже хтц (тогда самый актуальный) не мог поставлять обновления хоть с какой-то регулярностью.


          1. Revertis
            04.08.2015 10:32

            Но вы же понимаете, что сейчас таким образом обновляется только 1% от силы из всего того, что есть в системе?


            1. Poytu
              04.08.2015 10:48

              Если в этот 1% входят какие-то критические части ОС. Меня устраивает.
              Хотел бы я чтоб это было 100%? Да.
              Хотел бы я чтоб вендоры имели облегченные механизмы выпуска девайсов? Да.

              Меня устраивали идеи «андроид сильвер», «андроид уан» когда вендорам даются инструкции соблюдая, которые они могут получить актуальные обновления и более корректную поддержку железа.

              Ситуация в которой гугл тянет одеяло на себя, а вендоры спонсируют форки андроида, не красивая, но нормальная. По хорошему бы сесть всем за стол и придумать общие гайды, но везде люди и каждый хочет своего.


              1. livotov
                04.08.2015 12:47

                Если бы гугл смог «построить» вендоров, чтобы

                а) была обязательно опция в настройках, позволяющая переключиться на «чистый» интерфейс, без вендора изысков
                б) ввести какие-то четкие (более-менее) рамки по срокам выпуска новых версий вслед за reference-релизом а так же сроки поддежки устройств

                было бы уже просто отлично… И мне кажется, что для п.п. а и б у вендоров есть все необходимое, кроме, собственно, желания.
                Но вендорам пока выгоднее клепать новый телефон каждый месяц и забивать на поддержку всего, что было сделано до этого.


          1. livotov
            04.08.2015 12:38

            так и сейчас ситуация схожая, много ли не «родных» nexus устройств обновились до с 4.x до 5.0? А до 5.1?
            А те кто обновился — с какой задержкой…


      1. olegi
        21.08.2015 14:56

        Как мне кажется, вы смешиваете понятия Android как OS и GPS.
        Т.е. yandex\baido\etc придётся пилить самим часть OS, которую Google захотел забрать себе


  1. BRADA
    04.08.2015 08:43

    Только вот работает пока еще нестабильно. Понятно, что это пока DP.
    Когда допилят — будет киллер-фича.
    А пока при одинаковых режимах использования, без установки нового софта может за ночь то на пару процентов разрядиться



    то через пару суток всю ночь непонятно чем занимается и с утра реанимировать приходится, 40% уйдет.



    Все то же «Другое» в статистике, которое приследует пользователей начиная с L Developer Preview
    Пару раз вообще в 0 вырубал, ладно хоть будильник на руке (Pebble).


  1. seleko
    04.08.2015 16:33

    А вот народ жалуется, что в М не исправили.
    Вот и лоллипопина.


  1. mickvav
    04.08.2015 21:42

    А не будет проблемы типа — разлочил телефон, всё попросыпалось, полезло в инет, телефон повис.


    1. DZVang
      10.08.2015 10:01

      На одном из workshop'ов Google задавался этот вопрос, представитель ответил, что не замечал такого поведения)


  1. DjOnline
    22.09.2015 15:23

    Сообщения мессенджеров тоже не будут приходить в режиме глубокого сна?