Как разрешить работу в фоновом режиме на андроид

Как разрешить работу в фоновом режиме на андроид

Что такое фоновый режим и стоит ли закрывать фоновые приложения на Android?

Для многих людей вполне привычен процесс закрытия фоновых приложений на мобильном устройстве. И это вполне логично: при закрытии программ на компьютере освобождается ОЗУ и снижается нагрузка на процессор. Однако на смартфонах все устроено несколько иначе.

Что такое фоновый режим в андроид – куда на самом деле девается оперативная память?

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

Незакрытые андроид-приложения продолжают работать в фоновом режим?

Отчасти это так, однако «работать» – не совсем подходящее слово. Для начала нужно разобраться в теории. Практически все android-приложения состоят из двух основных частей:

  1. Видимая пользователю часть.
  2. Часть, которую пользователь не видит.

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

Переключаться между программами без потери данных можно до тех пор, пока мобильному устройству хватает ОЗУ. Как только заканчивается оперативная память, с которой могут работать приложения, операционная система начинает выгружать из памяти те приложения, которые давно не использовались, таким образом освобождая место в ней для используемых программ.

Ручное закрытие приложения и автоматическая выгрузка – практически одно и то же. При таких операциях из ОЗУ выгружается видимая пользователю часть приложения. Несохраненный прогресс будет утерян, а при повторном запуске программы пользователь увидит ее главный экран.

Приложения из меню многозадачности нельзя назвать полноценно работающими. На самом деле они являются лишь кэшированными данными, которые никак не влияют на производительность мобильного устройства и остаются в ОЗУ лишь для того, чтобы пользователь мог быстро вернуться к месту, на котором остановился.

Закрытие фоновых android-приложений улучшает производительность?

На самом деле это еще один миф. При очистке диспетчера задач вручную удастся освободить от силы 100-200 Мб, что никак не повлияет на производительность смартфона. Этот показатель может быть немного больше, если в меню многозадачности были игры, которые еще не выгрузились из оперативной памяти.

Куда на самом деле «утекает» память android-устройств? Как это проверить?

Несмотря не все факты, приведенные выше, объем свободной оперативной памяти на смартфоне с десятками установленных программ будет куда меньше, чем у только что распакованного мобильного устройства. Чтобы понять, куда именно девается оперативная память, необходимо разобраться с такими понятиями, как события и сервисы.

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

Сервисы – эта та часть мобильного приложения, которую пользователь не видит. Именно сервисы работают в фоновом режиме, занимают ОЗУ и разряжают мобильное устройство. Обычно сервисы начинают свою работу тогда, когда возникает какое-либо событие. Но бывает и так, что мобильное приложение может работать в фоновом режиме до тех пор, пока в панели уведомлений будет отображаться его иконка.

Чтобы проверить, на что именно расходуется оперативная память мобильного устройства, нужно включить режим разработчика и перейти к просмотру списка запущенных сервисов. Действовать нужно следующим образом:

  1. Перейдите в настройки смартфона.
  2. Войдите в раздел «О телефоне».
  3. Перейдите в подраздел «Информация об устройстве», а затем выберите пункт «Номер сборки» и кликните по нему 7 раз.
  4. Зайдите в раздел «Для разработчиков», а затем в подраздел «Статистика запущенных процессов».

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

Как действительно можно остановить чрезмерное потребление ресурсов мобильного устройства различными андроид-приложениями?

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

Однако это поможет всего на несколько минут, так как системные сервисы перезапустятся практически моментально, а сторонние после первого же события. В связи с этим подобную операцию можно назвать бессмысленной. Однако некоторые способы борьбы с ненужными android-сервисами все-таки существуют.

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

Программное обеспечение для заморозки android-приложений

Специализированные программы автоматически останавливают ненужные мобильному устройству сервисы, но останавливают их лишь частично. Для полноценной работы подобных программ необходимы root-права. Чтобы заморозить ненужные сервисы, скачайте специализированное приложение (например, Greenify), запустите его и выберите программы, службы которых вы хотите приостановить.

Отключение событий

Этот способ подойдет, если у вас есть root-доступ к своему мобильному устройству. В таком случае нет необходимости замораживать службы, так как можно сразу избавиться от причины их запуска – событий. Для этого нужно будет установить приложение Автостартс. При отключении событий ни в коем случае не трогайте системные, так как это может негативно отразиться на работе мобильного устройства. Также стоит учитывать, что после отключения сторонних событий некоторые программы могут работать хуже (пропадут некоторые автоматические действия, уведомления и т.д.).

Удаление программ

Это самый простой и в то же время наиболее радикальный способ. Достаточно просто избавиться от сторонних приложений, которые расходуют больше всего ресурсов мобильного устройства. Например, после удаления приложений социальных сетей вы практически ничего не потеряете, так как сможете сидеть на странице ВКонтакте или в Instagram через браузер, а вот экономия ОЗУ и заряда аккумулятора будет очень даже ощутима.

Выводы и советы

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

Как включить фоновый режим обмена данными

Чтобы использовать все возможности Play Маркета, необходимо включить на устройстве фоновый режим обмена данными. После этого приложения смогут скачивать нужные им файлы и показывать уведомления, даже когда вы в них не работаете. Для разных версий Android настройки могут отличаться. Подробнее о том, как проверить версию Android.

В режиме экономии трафика Google Play не всегда работает без подключения к Wi-Fi. Вы можете разрешить Google Play передавать мобильные данные в фоновом режиме даже при экономии трафика.

  1. Откройте приложение "Настройки" .
  2. Выберите Сеть и Интернет.
  3. Нажмите Передача данныхЭкономия трафика.
  4. Если этот режим выключен, ничего делать не нужно. В противном случае перейдите к следующему шагу.
  5. Нажмите Неограниченный мобильный Интернет.
  6. Прокрутите страницу вниз и выберите Google Play Маркет .
  7. Нажмите на нужный сервис или приложение.
  1. Откройте приложение "Настройки" .
  2. Нажмите Передача данныхПередача мобильных данных.
  3. Выберите сеть, для которой вы хотите посмотреть и ограничить трафик.
  4. Прокрутите страницу вниз и выберите Google Play Маркет .
  5. Нажмите Фоновый режимНеогранич. передача данных.
  1. Откройте приложение "Настройки" .
  2. В разделе "Беспроводные сети" выберите параметр Передача данных.
  3. В правом верхнем углу нажмите на значок меню .
  4. Установите флажок рядом с пунктом Автосинхронизация данных.
  5. В появившемся диалоговом окне "Включить синхронизацию?" нажмите ОК.

Примечание. Если интерфейс на вашем устройстве отличается от описанных вариантов, попробуйте выбрать Настройки Электропитание и передача данных Передача данных Фоновый режим.

Руководство по фоновой работе в Android. Часть 1

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

Будет несколько частей:

  1. Основной поток, осуществление фоновой работы с помощью AsyncTask, публикация результатов в основном потоке.
  2. Затруднения при использовании AsyncTask. Loaders как один из способов их избежать.
  3. Работа в фоне с помощью ThreadPools и EventBus.
  4. RxJava 2 как метод асинхронной работы.
  5. Корутины в Kotlin как метод асинхронной работы.

Начнем с первой части.

Основы UI

Первое, что следует понять, – почему мы вообще беспокоимся о работе в фоне в мобильных приложениях.

Во всех приложениях для Android есть хотя бы один поток, на котором происходит прорисовка UI и обработка пользовательского ввода. Поэтому он и называется потоком UI или главным потоком.

Каждый метод жизненного цикла каждого компонента вашего приложения, включая Activity, Service и BroadcastReceiver, исполняется на UI-потоке.

Человеческий глаз преобразовывает сменяющиеся изображения в плавное видео, если частота смены достигает 60 кадров в секунду (да, это магическое число берется отсюда), давая основному потоку только 16 мc для прорисовки всего экрана.

Продолжительность сетевого вызова может быть в тысячи раз больше.

Когда мы хотим загрузить что-либо из Интернета (прогноз погоды, пробки, сколько стоит ваша часть биткоина в данный момент), мы не должны делать это из главного потока. Более того, Android не позволит нам, выбросив NetworkOnMainThreadException.

Семь лет назад, когда я разрабатывал свои первые приложения на Android, подход от Google был ограничен использованием AsyncTasks. Давайте посмотрим, как мы писали код для общения с сервером (псевдокод преимущественно):

Метод doInBackground() гарантированно будет вызван не на основном потоке. Но на каком? Зависит от реализации. Вот как Android выбирает поток (это часть исходного кода класса AsyncTask):

Здесь можно увидеть, что выполнение зависит от параметра Executor. Посмотрим, откуда он берется:

Как здесь указано, по умолчанию executor ссылается на пул потоков размера 1. Это означает, что все AsyncTasks в вашем приложении запускаются последовательно. Это не всегда было верно, так как для версий ОС от DONUT до HONEYCOMB использовался пул размером от 2 до 4(в зависимости от количества ядер процессора). После HONEYCOMB AsyncTasks снова выполняются последовательно по умолчанию.

Итак, работа выполнена, байты закончили свое длинное путешествие с другого полушария. Нужно превратить их во что-то понятное и разместить на экране. К счастью, наша Activity тут как тут. Давайте поместим результат в одно из наших View.

О, черт! Опять исключение!

Но мы не делали никаких сетевых обращений на основном потоке! Правильно, но мы попытались нарушить другой закон UI. Пользовательский интерфейс можно менять только из UI-потока. Это верно не только для Android, но и практически для любой системы, с которой вы столкнетесь. Причину этого хорошо объяснили в Java Concurrency In Practice. Вкратце – архитекторы хотели избежать сложной блокировки при изменениях из нескольких источников (пользовательский ввод, биндинг и другие изменения). Использование единственного потока решает эту проблему.

Да, но UI все равно нужно обновлять. У AsyncTask есть еще метод onPostExecute, который вызывается на UI-потоке:

Как эта магия работает? Посмотрим в исходном коде AsyncTask:

AsyncTask использует Handler для вызова onPostExecute в UI, ровно как и метод postOnUiThread в компонентах Android.

Handler прячет всю внутреннюю кухню. Какую именно? Идея состоит в том, чтобы иметь бесконечный цикл проверки сообщений, приходящих на UI-поток, и обрабатывать их соответствующе. Велосипедов тут никто не изобретает, хотя без кручения педалей не обошлось.

Для Android это реализовано классом Looper, который передается в InternalHandler в приведенном выше коде. Суть класса Looper находится в методе loop:

Он просто опрашивает очередь входящих сообщений в бесконечном цикле и обрабатывает эти сообщения. Это означает, что на UI-потоке должен быть инициализированный экземпляр Looper. Можно получить доступ к нему с помощью статического метода:

Кстати, вы только что узнали, как проверить, вызывается ли ваш код в UI-потоке:

Если вы попытаетесь создать экземпляр Handler в методе doInBackground, то получите другое исключение. Оно сообщит о необходимости наличия Looper для потока. Теперь вы знаете, что это значит.

Надо заметить, что AsyncTask может быть создан только в UI-потоке по указанным выше причинам.
Вы можете подумать, что AsyncTask – это удобный способ выполнения фоновой работы, так как он скрывает сложность и требует немного усилий при использовании, но есть несколько проблем, которые приходится решать по пути:

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

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

Ссылка на основную публикацию