- Решение проблемы с MediaServer — быстро разряжается батарея на Android
- Что такое MediaServer на Android?
- Совет 1. Безопасное извлечение.
- Совет 2. Использование качественных карт памяти.
- Решение проблемы 1. MP3Val.
- Решение проблемы 2. Удаление поврежденных файлов.
- Решение проблемы 3. Форматирование карты памяти.
- Решение проблемы 4. Приложение MediaServer Killer.
- Служба (Service)
- Создание службы
- Жизненный цикл служб
- Запуск сервиса и управление его перезагрузкой
- Запуск и остановка служб
- PlayService.java
- Пример для Kotlin
- Список всех запущенных сервисов
- Ущемление прав службы
- Системные службы
Решение проблемы с MediaServer — быстро разряжается батарея на Android
23 июля 2016 | Просмотров: 14595 | |
Большинство производителей смартфон стараются сделать свои устройства максимально компактными. Если учесть, что уменьшить размеры материнской платы, экрана и прочих комплектующих невозможно, то жертвовать приходится аккумулятором. Если не рассматривать отдельную категорию смартфонов-долгожителей, то среднестатистический девайс живет от одного заряда всего 1-2 дня. При этом операционная система Android не лишена программных багов, которые могут еще больше ускорить процесс разрядки. Одним из таких сервисов-паразитов является MediaServer или же Server Media, который висит в памяти и садит аккумулятор. В этой статье мы расскажем о причинах и способах решения излишнего разряда. Что такое MediaServer на Android?Если вдаваться в теорию, то процесс MediaServer отвечает за сканирование памяти устройства (внутреннего накопителя и карточки памяти) на наличие мультимедийных файлов. Если все работает корректно, то после завершения сканирования процесс самостоятельно завершается, на забивая оперативную память и не расходуя заряд аккумулятор. Если же один из файлов поврежден или имеет неправильную структуру, то процесс MediaServer продолжает сканировать его до бесконечности, тем самым сажая батарейку за считанные часы. Совет 1. Безопасное извлечение.Устройства со старыми версиями Android (до Android 5.0) подключаются к компьютеру в качестве накопителя. То есть ваш смартфон или планшет распознается как обычная флешка. Если это так, то оптимальным способом избежать ошибок с медиафайлами станет безопасное извлечение Android. Для этого нажмите на соответствующий значок в нижнем правом углу и выберите строчку «Извлечь» напротив нужного устройства. Совет 2. Использование качественных карт памяти.Чтобы избежать проблем с чтением файлов, а также зависания процесса MediaServer, мы рекомендуем вам использовать качественные карты памяти. Заказанные на aliexpress карточки microSD стоят немного дешевле, однако зачастую они показывают очень низкую скорость чтения и записи, не соответствуют заданному классу и вызывают большое количество сбоев в работе. Если вы любите слушать музыку и смотреть фильмы, то стоит один раз потратиться на фирменную карту памяти, которая продается с гарантией. Решение проблемы 1. MP3Val.Как мы уже писали ранее, проблема с зависанием и излишним расходом заряда аккумулятора на процесс MediaServer связана с ошибками с медиафайлах. Таким образом, если на вашем смартфоне или планшете хранится большое количество музыки, то с большой долей вероятности, проблема именно в ней.
Решение проблемы 2. Удаление поврежденных файлов.Если на вашем Android-устройстве присутствуют недокачанные видео или аудио файлы, то попробуйте просто удалить их вручную. Вполне вероятно, что это решит проблему с процессом MediaServer. Решение проблемы 3. Форматирование карты памяти.Сохраните все нужные вам файлы с мобильного устройства на персональном компьютере. После этого зайдите в настройки девайса, раздел «Память» и выполните очистку карты памяти, как это указано на картинке. Стоит учесть, что после этого все содержимое данного накопителя будет стерто. Решение проблемы 4. Приложение MediaServer Killer.Если все перечисленные выше варианты не сработали, и процесс MediaServer продолжает нещадно потреблять заряд аккумулятора, то можно воспользоваться специальной утилитой. Название MediaServer Killer говорит само за себя. Данная программа принудительно завершает процесс MediaServer при длительной работе. Однако стоит учесть, что утилита MediaServer Killer потребует наличия Root-прав на вашем гаджете. Источник Служба (Service)Службы (Сервисы) в Android работают как фоновые процессы и представлены классом android.app.Service. Они не имеют пользовательского интерфейса и нужны в тех случаях, когда не требуется вмешательства пользователя. Сервисы работают в фоновом режиме, выполняя сетевые запросы к веб-серверу, обрабатывая информацию, запуская уведомления и т.д. Служба может быть запущена и будет продолжать работать до тех пор, пока кто-нибудь не остановит её или пока она не остановит себя сама. Сервисы предназначены для длительного существования, в отличие от активностей. Они могут работать, постоянно перезапускаясь, выполняя постоянные задачи или выполняя задачи, требующие много времени. Клиентские приложения устанавливают подключение к службам и используют это подключение для взаимодействия со службой. С одной и той же службой могут связываться множество клиентских приложений. Android даёт службам более высокий приоритет, чем бездействующим активностям, поэтому вероятность того, что они будут завершены из-за нехватки ресурсов, заметно уменьшается. По сути, если система должна преждевременно завершить работу запущенного сервиса, он может быть настроен таким образом, чтобы запускаться повторно, как только станет доступно достаточное количество ресурсов. В крайних случаях прекращение работы сервиса (например, задержка при проигрывании музыки) будет заметно влиять на впечатления пользователя от приложения, и в подобных ситуациях приоритет сервиса может быть повышен до уровня активности, работающей на переднем плане. Используя сервис, можете быть уверены, что ваши приложения продолжат работать и реагировать на события, даже если они в неактивном состоянии. Для работы службам не нужен отдельный графический интерфейс, как в случае с активностями, но они по-прежнему выполняются в главном потоке хода приложения. Чтобы повысить отзывчивость вашего приложения, нужно уметь переносить трудоёмкие процессы (например, сетевые запросы) в фоновые потоки, используя классы Thread и AsyncTask. Службы идеально подходят для проведения постоянных или регулярных операций, а также для обработки событий даже тогда, когда активности вашего приложения невидимы, работают в пассивном режиме или закрыты. Сервисы запускаются, останавливаются и контролируются из различных компонентов приложения, включая другие сервисы, активности и приёмники широковещательных намерений. Если ваше приложение выполняет задачи, которые не зависят от прямого взаимодействия с пользователем, сервисы могут стать хорошим выбором. Запущенные сервисы всегда имеют больший приоритет, чем бездействующие или невидимые активности, поэтому менее вероятно, что их работа завершится преждевременно при распределении ресурсов. Единственная причина, почему Android может досрочно остановить Сервис, — выделение дополнительных ресурсов для компонентов, работающих на переднем плане (как правило, для активностей). Если такое случится, ваш сервис автоматически перезапустится, когда будет достаточно доступных ресурсов. Когда сервис напрямую взаимодействует с пользователем (например, проигрывая музыку), может понадобиться повысить его приоритет до уровня активностей, работающих на переднем плане. Это гарантия того, что сервис завершится только в крайнем случае, но при этом снижается его доступность во время выполнения, мешая управлять ресурсами, что может испортить общее впечатление от приложения. Приложения, которые регулярно обновляются, но очень редко или нерегулярно взаимодействуют с пользователем, можно назвать первыми кандидатами на реализацию в виде сервисов. Проигрыватели MP3 и приложения, отслеживающие спортивные результаты, — примеры программ, которые должны постоянно работать и обновляться без необходимости отображать активность. Создание службыЧтобы определить службу, необходимо создать новый класс, расширяющий базовый класс Service. Можно воспользоваться готовым мастером создания класса для сервиса в Android Studio. Щёлкаем правой кнопкой мыши на папке java (или на имени пакета) и выбираем New | Service | Service: В следующем окне выбираем имя сервиса (флажки оставляем) и нажимаем кнопку Finish. При этом сервис автоматически зарегистрируется в манифесте в секции . Если бы мы убрали флажки на экране мастера, то оба атрибута имели бы значение false. Например, атрибут exported даёт возможность другим приложениям получить доступ к вашему сервису. Имеются и другие атрибуты, например, permission, чтобы сервис запускался только вашим приложением. Также вы можете обойтись без мастера и создать вручную класс сервиса и запись в манифесте, теперь вы знаете, из чего он состоит. Жизненный цикл службПодобно активностям служба имеет свои методы жизненного цикла: Для быстрого создания заготовок нужных методов используйте команду меню Code | Override Methods. или набирайте сразу имя метода, используя автодополнение. Реализуя эти методы обратного вызова в своей службе, вы можете контролировать жизненные циклы службы. В полном жизненном цикле службы существует два вложенных цикла:
Из своего приложения службу можно запустить вызовом метода Context.startService(), остановить через Context.stopService(). Служба может остановить сама себя, вызывая методы Service.stopSelf() или Service.stopSelfResult(). Можно установить подключение к работающей службе и использовать это подключение для взаимодействия со службой. Подключение устанавливают вызовом метода Context.bindService() и закрывают вызовом Context.unbindService(). Если служба уже была остановлена, вызов метода bindService() может её запустить. Методы onCreate() и onDestroy() вызываются для всех служб независимо от того, запускаются ли они через Context.startService() или Context.bindService(). Если служба разрешает другим приложениям связываться с собой, то привязка осуществляется с помощью дополнительных методов обратного вызова:
В метод обратного вызова onBind() передают объект Intent, который был параметром в методе bindService(), а в метод обратного вызова onUnbind() — объект Intent, который передавали в метод unbindService(). Если служба разрешает связывание, метод onBind() возвращает канал связи, который используют клиенты, чтобы взаимодействовать со службой. Метод обратного вызова onRebind() может быть вызван после onUnbind(), если новый клиент соединяется со службой. Запуск сервиса и управление его перезагрузкойВ большинстве случаев также необходимо переопределить метод onStartCommand(). Он вызывается каждый раз, когда сервис стартует с помощью метода startService(), поэтому может быть выполнен несколько раз на протяжении работы. Вы должны убедиться, что ваш сервис это предусматривает. Метод onStartCommand() заменяет устаревший метод onStart(), который использовался в Android 2.0. В отличие от onStart() новый метод позволяет указать системе, каким образом обрабатывать перезапуски, если сервис остановлен системой без явного вызова методов stopService() или stopSelf(). Службы запускаются в главном потоке приложения; это значит, что любые операции, выполняющиеся в обработчике onStartCommand(), будут работать в контексте главного потока GUI. На практике при реализации сервиса в методе onStartCommand() создают и запускают новый поток, чтобы выполнять операции в фоновом режиме и останавливать сервис, когда работа завершена. Такой подход позволяет методу onStartCommand() быстро завершить работу и даёт возможность контролировать поведение сервиса при его повторном запуске, используя одну из констант.
Обратите внимание, что при окончании всех операций каждый из этих режимов требует явной остановки сервиса с помощью методов stopService() или stopSelf(). Режим перезапуска, который вы указываете в качестве значения, возвращаемого методом onStartCommand(), будет влиять на параметры, передаваемые при последующих вызовах. Изначально намерение выступает в качестве параметра, который передастся в метод startService() при запуске сервиса. После перезапуска системой он может иметь значение null (если установлен режим START_STICKY) или оригинальное (если установлен флаг START_REDELIVER_INTENT). Параметр flag может помочь узнать, как именно был запущен сервис:
Запуск и остановка службЧтобы запустить службу, в клиентском приложении необходимо вызывать метод startService(). Существует два способа вызова службы: Пример для явного вызова службы с именем MyService: Также можно явно определить службу, создав экземпляр класса этой службы. Пример неявного вызова службы: Чтобы использовать этот пример, необходимо включить константу SERVICE_ACTION, идентифицирующую службу, в класс MyService, например: Используйте фильтр намерений, чтобы зарегистрировать его как провайдера SERVICE_ACTION. Если служба потребует разрешений, которые не имеет ваше приложение, то запрос вызовет исключение SecurityException. Как только сервис завершил выполнение тех действий, для которых он запускался, вы должны вызвать метод stopSelf() либо без передачи параметра, чтобы ускорить остановку работы, либо передав значение startId, чтобы убедиться, что задачи выполнены для всех экземпляров, запущенных с помощью вызова startService(), как показано в следующем фрагменте: Явная остановка сервиса по завершении необходимых задач позволяет системе получать обратно ресурсы, которые в ином случае оставались бы заняты. Поскольку приоритет сервисов повышенный, система, как правило, не завершает их работу, поэтому её окончание по собственной инициативе может существенно улучшить эффективность использования ресурсов вашим приложением. Для остановки работы используйте метод stopService(), передавая ему объект Intent, определяющий нужный сервис. Если метод startService() вызывается для сервиса, который уже работает, обработчик onStartCommand(), принадлежащий объекту Service, будет вызван повторно. Вызовы startService() не накапливаются, поэтому единственный вызов метода stopService() завершит работу сервиса, неважно, сколько раз производился вызов startService(). Давайте создадим практическое приложение для работы со службой. Наша служба будет запускать на воспроизведение музыкальный файл, который будет проигрываться в фоновом режиме. Управлять службой можно будет из активности. Создайте новый проект. Для службы создайте отдельный класс PlayService. Служба будет загружать музыкальный файл sample.mp3 из каталога res/raw/ (разместите там свой MP3-файл). PlayService.javaЗарегистрируем службу в файле манифеста. В файле разметки для активности определим две кнопки: Старт и Стоп: В классе активности в обработчиках событий кнопок будем вызывать методы startService() и stopService() для управления службой. Запущенная служба будет выполняться независимо от состояния активности, несмотря на то, что эти компоненты находятся в одном приложении: если её завершить, служба все равно останется работать. Если вы хотите, чтобы сервис запускался и после перезагрузки устройства, то следует создать приёмник широковещательных сообщений и запустить в нём сервис. Приёмник регистрируется в манифесте с именем действия BOOT_COMPLETED: Пример для KotlinКласс для службы, которая будет генерировать случайные числа через определённый промежуток времени. Не забудьте прописать службу в манифесте. Разместите на экране активности три кнопки: запуск, остановка и статус службы. Код для активности. Список всех запущенных сервисовУщемление прав службыGoogle последовательно борется с ограничениями для служб, урезая их возможности. Делается это для того, чтобы службы не висели в памяти бесконечно долго и тратили заряд батареи. Ограничение возможностей происходит постепенно от версии к версии. В последних версиях уже можно столкнуться с примерами, когда выкидывается исключение при неправильной работе с службами. Для решения проблем следует изучить такие вещи как JobScheduler, Firebase Job Dispatcher, WorkManager. Также появилось понятие Foreground service. Системные службыКроме создания собственных сервисов, вы можете использовать системные сервисы. Вот небольшой список:
Источник |