No background process android process

Руководство по фоновой работе в 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.

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

android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

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

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

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

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

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

Читайте также:  Otg провод для андроид

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

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

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

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

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

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

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

Источник

Usage of android:process

I have this AndroidManifest.xml file:

«android:process» is added both as manifest tag and provider tag, I know if it is added as a provider tag, the provider can be run in the «com.lily.process» process. But what’s the usage of it when written as a manifest tag? I have tried, but not all components could be running in the process it identified.

4 Answers 4

I would agree that not many people would find android:process to be useful as an attribute of the application tag. However, I have found it to be useful as an attribute of the activity tag.

The purpose of android:process on an activity is to specify that your activity should be launched in a process having a specific name. The choice of that name may be used either to isolate the activity in its own process (different from the one that launched it), or to force it to cohabit in a single process with other activities that use the same name.

«If the name assigned to this attribute begins with a colon (‘:’), a new process, private to the application, is created when it’s needed and the activity runs in that process. If the process name begins with a lowercase character, the activity will run in a global process of that name, provided that it has permission to do so. This allows components in different applications to share a process, reducing resource usage.»

I have recently found this attribute to be useful in solving a problem I had with launching a help activity for an app that, under certain circumstances, was fairly close to the 16MB heap limit that still applies to some devices. Launching its help activity was, in those situations, pushing my app over the limit, resulting in a force close.

By using the android:process tag, I was able to specify that my help activity should be launched in a separate process of its own. This process had its own 16MB heap, and it was not counted against the heap of my main app that launched it. This permanently and completely prevented my app from running out of heap space and crashing when help was launched.

If your launching app has the package name

and is therefore assigned a process name that is that same string, then, if you use

on your launched activity, it will be assigned the process name

and that process will have its own, separate process ID, which you can view (for example in DDMS).

That, at least, has been my experience. My testing has so far been performed on an old Moto Droid running CM6 (Android 2.2.1), configured to have a 16MB heap limit.

In my case, since I did not want the user to perceive the help as being separate from my app, I included the

Читайте также:  Прошивка samsung a300f android 7

attribute to prevent the help activity from appearing on the recent apps (long-press Home) list. I also included

where HelpActivity is the name of the help activity, to segregate the activity in its own task

to prevent multiple instances of this app from being created each time the user invoked help.

I also added the flag:

to the Intent used to launch the help activity.

These parameters may or may not be needed, depending upon the use that you are making of the android:process attribute.

Considering how often one encounters memory limits when developing for Android devices, having a technique that can, in some cases, allow you to break out parts of your app into separate processes, each with its own heap, seems like a wonderful gift. There may be hidden hazards in doing this that I have not yet considered or experienced, but so far, so good, in my particular instance.

Источник

Что такое фоновые процессы в Android и как их отключить

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

Зачем нужны фоновые приложения и в чем их вред

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

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

Как узнать запущенные фоновые процессы

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

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

Какие приложения можно останавливать

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

Система Андроид устроена так, что важные для работы телефона программы не позволят владельцу гаджета закрыть их фоновые процессы. Не рекомендуется к тому же отключать скрытые операции приложений, которые находятся в постоянном использовании, к примеру мессенджеров, так как от них перестанут приходить оповещения, возможно, важные для пользователя. Базовые приложения, названия которых начинается со слова «Google», например, Google Search, Google Play Store, останавливать также не стоит.

Как отключить приложения

Андроид позволяет владельцу смартфона вносить значительные изменения в его работу, в том числе запретить скрытые процессы большинства программ. Для этого необходимо:

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

Также можно воспользоваться специальными утилитами, предназначенными для автоматизации гаджета, например:

  • Greenify;
  • ES Task Manager;
  • Clean Master;
  • Advanced Task Manager;
  • ShutApp;
  • Naptime.

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

Источник

Debugging Android process death

Learn this now or spend 🤷‍♂️ in Crashlytics later

Mar 12 · 4 min read

Читайте также:  Слот машина для андроид

In this series, we spoke at length about how Android process death can trigger crashing on apps that do not follow a Clean MVVM Application lifecycle pattern. In order to debug Android process death, you need to first trigger a process death, and then you need to restore your application to see how it behaves.

Step 1: Trigger process death

Method A: Use adb

Put your app into the background by pressing the home button

Kill the app using adb :

❗ DON’T use the “Stop” button of Android Studio to kill the process. This will not simulate a process death and it will falsely make you believe that your app is protected. This will indeed kill the app, but next time you launch it, it will go through the normal flow of the LAUNCHER Activity, instead of re-creating the Activity you were in before moving the app to the background.

Method B: Do it naturally

You can also use the following technique if you don’t have adb access for some reason:

From Developer Options , set the Background process limit to No background processes

Move the app to the background by pressing the home button

Launch a few other apps, like Phone or Messages or Chrome.

Tip: Use the Android Studio’s “Attach Debugger to Android Process” window to know when your app has actually been killed.

Step 2: Restore your app and see how it behaves

When the process has been killed, use the square “app switcher” aka Recents screen to navigate back into your app. This will cause the OS to try to resume your app directly from the last screen it was on.

Additional tips

If there is a crash with a small amount of logs in Crashlytics or if you see logs for an Activity getting created without seeing the launch activity of your app being created, then if it’s not a deep link or a notification, it’s almost certainly a process death scenario that you can reproduce by following the steps above.

Debugging the back stack chain

There’s an additional tricky part to debugging android process death:

Only the Activity that you were in will be recreated once you foreground the app.

That means that every time you tap the Back arrow, the parent activity will be picked up from the back stack and get recreated as well. So essentially, all Activities in the back stack will experience restoration from a process death and the state of the Application could vary, depending on the operations that the recreated activities have performed (i.e. whether they have modified any application-scoped data).

When debugging process death for Activity A, try doing so both by backgrounding Activity A itself, and from child Activity B + pressing Back to return to Activity A

A note about fragments

When an Activity creates a Fragment, and you background the app while the Fragment is visible, then when the Activity is restored after a process death, it is not guaranteed that the onCreate() of the Activity will have completed before the onCreate() of the Fragment. So if you have shared data between the Activity and the Fragment, you might crash if the Fragment tries to access them before the Activity initializes them.

Further reading

  • Android Activity Lifecycle considered harmful
  • Android process death
  • Clean MVVM Activity Lifecycle
  • Repository Initialization
  • Activity Lifecycle Cheat Sheet
  • Debugging Android process death ← you are here

One more thing…

If you’re a mobile developer who enjoys app architecture, are interested in working for a values-first app company serving the queer community, talk to us! Visit https://www.scruff.com/careers for info about jobs at Perry Street Software

Other series you might like

Clean API Architecture (2021)
Classes, execution patterns, and abstractions when building a modern API endpoint.

Kotlin in Xcode? Swift in Android Studio? (2020)
A series on using Clean + MVVM for consistent architecture on iOS & Android

About the authors

Eric Silverberg and Stelios Frantzeskakis are developers for Perry Street Software , publishers of the LGBTQ+ dating apps SCRUFF and Jack’d , with more than 20M members worldwide.

Источник

Оцените статью