что такое процесс android

Русские Блоги

Android процессы и потоки

Table of Contents generated with DocToc

[Android процессы и темы]

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

Конечно, мы также можем позволить различным компонентам приложения работать в разных процессах, и мы также можем открывать новые потоки в любом процессе для выполнения задач.

Android-процесс

Жизненный цикл процесса

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

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

Уровень важности делится на 5 уровней от высокого до низкого:

1. Процесс переднего плана

Процесс, в настоящее время взаимодействующий с пользователем. Если процесс P удовлетворяет любому из следующих условий, процесс P называется процессом переднего плана:

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

2. Видимый процесс

В этом процессе не выполняется ни один компонент переднего плана, но он все равно может влиять на экран, который видит пользователь. Если процесс P удовлетворяет любому из следующих условий, процесс P называется видимым процессом:

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

3. Процесс обслуживания

Если одинслужба запускается методом startserviceИ не относится к вышеупомянутым двум случаям более высокого уровня, тогда процесс, выполняющий службу, называется процессом службы. Хотя сервис не привязан к какому-либо компоненту, который может видеть пользователь, работа, которую он выполняет, касается пользователя, например, воспроизведение музыки, загрузка файла и т. Д.

4. Фоновый процесс Фоновый процесс

Некоторые текущиеНевидимая деятельность(ПерезвониonStopСпособ) Запускаем по этой теме. Такие потоки не могут напрямую влиять на взаимодействие с пользователем, и система может в любой момент уничтожить такие процессы, чтобы освободить память для трех указанных процессов. Обычно естьНесколько фоновых процессовБегут, чтобы ониСохранено вОдинСписок LRU, Чтобы процессы, которые реже всего использовались пользователями, были убиты первыми. Если активность обычно вызывает функции своего жизненного цикла и сохраняет соответствующие данные о состоянии, то уничтожение фонового процесса не повлияет на работу пользователя. Потому что, когда пользователь пытается вернуться к операции, система восстановит все состояние активности.

5. Пустой процесс

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

В системе Android уровень процесса может динамически увеличиваться, поскольку другие процессы могут зависеть от процесса. Процесс предоставляет услуги для других процессов, затемУровень процесса не должен быть ниже, чем процесс, который он обслуживает, Например, если поставщик контента работает в процессе A, он обслуживает клиента B в процессе B, или если услуга в процессе A связана с компонентом в процессе B, тогда важность процесса A будет только высокой Равно или равно процессу Б.

мульти-Прогресс

Многопроцессные преимущества

Многопроцессная реализация

Есть два способа установить атрибут процесса:

Какие подводные камни

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

1) Многократные реконструкции Приложения.

2) Отказ статических элементов.

3) Проблемы с обменом файлами.

4) Проблема отладки точки останова.

Приложение несколько перестраивает

Давайте рассмотрим первый случай на простом примере.

Как упоминалось выше, файл Manifest определяет два класса: ProcessTestActivity и ProcessTestService.Мы только что запустили службу непосредственно в методе onCreate в Activity. В то же время мы настроили наш собственный класс Application. код шоу, как показано ниже:

Выполните приведенный выше код для просмотра информации о печати:

что такое процесс android. Смотреть фото что такое процесс android. Смотреть картинку что такое процесс android. Картинка про что такое процесс android. Фото что такое процесс android

мы обнаруживаемМетод onCreate MyApplication вызывается дваждыСоответственно при запуске ProcessTestActivity и ProcessTestService мы обнаружили, что напечатанный pid также отличается. Поскольку некоторые глобальные операции инициализации обычно выполняются в методе onCreate Application, инициализировать их несколько раз совершенно не нужно.
Это происходит потому, что дажеКогда новый процесс запускается путем указания атрибута процесса, система также создает отдельную виртуальную машину, и, естественно, ее необходимо повторно инициализировать. Приложение, Так как решить эту проблему?

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

После запуска проверьте информацию журнала,

что такое процесс android. Смотреть фото что такое процесс android. Смотреть картинку что такое процесс android. Картинка про что такое процесс android. Фото что такое процесс android

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

Отказ статических членов

Теперь давайте посмотрим на второй вопрос и просто изменим код Activity и Service, определенный ранее, код выглядит следующим образом:

Повторно выполнить код и распечатать журнал

что такое процесс android. Смотреть фото что такое процесс android. Смотреть картинку что такое процесс android. Картинка про что такое процесс android. Фото что такое процесс android

Проблемы с обменом файлами

Проблемы отладки точек останова

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

подводить итоги

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

Тема Android

Пользовательский интерфейс

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

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

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

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

рабочая нить

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

ASYNC TASK

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

Потокобезопасный метод

В большинстве случаев наш метод может вызываться несколькими потоками, поэтому мы должны рассмотреть вопрос о безопасности потоков. Это особенно верно для тех методов, которые можно вызывать удаленно, например, метод привязки службы. Когда мы пытаемся вызвать метод, реализованный в IBinder, если вызывающая сторона и IBinder находятся в одном и том же процессе, то метод будет выполнен в потоке вызывающей стороны. Если вызывающая сторона и IBinder не находятся в одном и том же процессе, система берет поток из пула потоков, поддерживаемого для выполнения метода, пул потоков и IBinder выполняются в одном и том же процессе (не выполняется в потоке пользовательского интерфейса). Например, хотя поток пользовательского интерфейса процесса службы будет вызывать метод onBind службы, эти методы, реализованные в объекте IBinder, возвращенном методом onBind, будут выполняться потоками в пуле потоков. Поскольку к службе могут обращаться несколько клиентов, несколько потоков в пуле потоков могут одновременно вызывать один и тот же метод. Следовательно, метод, реализованный в объекте IBinder, должен быть потокобезопасным.

Аналогично, ContentProvider может получать запросы данных от различных процессов. Хотя детали управления межпроцессным взаимодействием скрыты в классах CP и CR, соответствующий запрос, удаление, изменение, вставка и другие методы запроса в CP будут переданы. Поток в пуле потоков процесса, в котором находится CP, выполняется. Эти методы могут вызываться несколькими процессами одновременно, поэтому эти методы должны быть поточно-ориентированными.

Межпроцессного взаимодействия

Система Android предоставляет механизм удаленного вызова RPC для завершения процесса IPC связи процесса. Через механизм RPC компоненты (такие как действия) в прикладной программе вызывают метод локально в качестве вызывающего, а метод выполняется удаленно (в другом процессе), а затем Верните результат вызывающей стороне. Для этого требуется, чтобы вызываемый метод и его данные были проанализированы до степени, понятной операционной системе, а затем переданы из локального процесса и адресного пространства в удаленный процесс и адресное пространство, а затем реорганизованы и выполнены.

Android Advanced 13: сравнение и краткое описание нескольких методов взаимодействия процессов

05 июня 2017 г. 01:16:48

Прочитав эту статью, вы узнаете:

Что такое RPC

RPC типиченРежим клиент / сервер, Клиент отправляет серверу ряд запросов, сервер работает в соответствии с параметрами, предоставленными клиентом после его получения, и затем возвращает результат выполнения клиенту.

В объектно-ориентированном программировании это также называется «удаленным вызовом метода».

Что такое IDL

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

IDL расшифровывается как язык описания интерфейса.

Он описывает интерфейсы нейтральным образом, чтобы объекты, работающие на разных платформах, и программы, написанные на разных языках, могли общаться друг с другом., Например, если один компонент написан на C ++, а другой компонент написан на Java, он все еще может взаимодействовать.

Что такое МПК

IPC расшифровывается как межпроцессное взаимодействие.

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

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

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

Android несколько процессов общения

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

Затем возвращаемое значение будет передано обратно в обратном направлении.

Android предоставляет нам следующие механизмы взаимодействия процессов (API взаимодействия процессов для разработчиков). Ссылки на соответствующие статьи:

Источник

Android Process: Я тебя породил, я тебя и …

что такое процесс android. Смотреть фото что такое процесс android. Смотреть картинку что такое процесс android. Картинка про что такое процесс android. Фото что такое процесс android

Как оказалось, нужный механизм уже имеется в SDK, и это… барабанная дробь… Кнопка «Terminate Application».

что такое процесс android. Смотреть фото что такое процесс android. Смотреть картинку что такое процесс android. Картинка про что такое процесс android. Фото что такое процесс android

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

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

Ситуация 1: Статик — это не надёжно

Как видно из кода, в первой Activity разработчик решил не “заморачиваться” и поместил данные в статические переменные. Это весьма соблазнительно, когда нужно передать достаточно неординарный объект, не поддающийся простой сериализации. Над второй Activity он тоже не долго думал и не сделал проверки на нул. Зачем, когда первая Activity всё уже сделала?

Проделываем описанную ранее последовательность по корректному уничтожению процесса на второй Activity. Приложение падает.

Что случилось?
Проблема тут не в отсутствии проверки на null. Самая страшная проблема — это потеря пользовательских данных. Статические объекты не должны быть хранилищем данных, особенно если это их единственное место. Касается это как обычных переменных так и синглтонов. Так что если в статике хранится что-то важное, будьте готовы это важное потерять в любой момент.

Что делать?
Наличие таких ошибок, зачастую, свидетельствует о низкой квалификации программиста, либо о слишком высоком чувстве лени. О том как делать правильно, написано огромное количество туториалов. В приведенном примере лучше всего подойдёт передача данных через бандл. Также можно писать эти данные в SharedPreferences, либо стоит задуматься о создании базы данных.
Важно: Не стоит забывать, что синглтон это тоже статик переменная. Если вы используете синглтон, то он должен выступать лишь как инструмент облегчающий доступ к данным, но ни как не быть единственным хранилищем для них.

Волшебная сила Application
Как часто я вижу советы использовать класс Application как синглтон либо инициализировать синглтон в методе onCreate() класса Application. Якобы после этого он станет круче чем Ленин, то есть будет живее всех живых при любых обстоятельствах. Возможно, это частный случай заблуждения встретившийся только мне. Причем, все публикации которые я находил, явно не заявляют о подобных свойствах синглтона. В некоторых из них говорится, что синглтон может быть уничтожен сборщиком мусора если инициировать его в классе Activity (что для меня звучит немного дико). В других пугают выгрузкой класса из класслоадера (а это уже похоже на правду).

Сейчас я не собираюсь выяснять, что тут правда а что домыслы. В любом случае это лишь снижает вероятность потери статик ссылки но ни как не спасает от остановки процесса. Остановка процесса приведет к полному уничтожению класслоадера, а вместе с ним и уничтожению всех классов, включая класс Application.

Ситуация 2: setRetainInstance как решение всех проблем

Такая реализация — стойка к любым вращениям экрана. Все будет работать как часы. До поры до времени…
Применим последовательность действий для хитрого уничтожения процесса, когда диалог открыт. При разворачивании ничего не произойдет. Однако, при вызове invokePersonChoose приложение вылетит с NullPointerException.

Что случилось?
setRetainInstance(true) не позволяло диалогу уничтожиться. После уничтожения процесса диалог все-таки был уничтожен. Activity восстанавливает фрагмент насколько это возможно. К сожалению, слушатель не восстанавливается, так как он был установлен совершенно в другом месте для совершенно другого объекта. Когда в диалоге, в методе invokePersonChoose, происходит обращение к слушателю, выбрасывается исключение. И беда тут не в отсутствии проверки на null. Поставить проверку на null без должной реакции на пустую ссылку будет еще более худшим решением.

Единственное, что не стоит забывать, Activity может быть уже уничтожена когда дело дойдет до отправки сообщения. Поэтому обязательно проверьте добавлен ли фрагмент на Activity.
По мимо Activity можно использовать родительский фрагмент или Target фрагмент.

Еще пара слов про setRetainInstance
Замечу, это лишь частный случай с setRetainInstance. Количество проблем которые он может скрыть(а не решить) немного больше. Вместе со слушателями также теряются и все остальные переменные. Все, что не было сохранено в методе onSaveInstanceState, будет потеряно.
Также, он скрывает проблему когда класс диалога анонимный. Допустим, в момент создания нового объекта диалога, переопределен какой либо метод, в этом случае создастся объект анонимного класса.

Если этот диалог будет уничтожен и система попытается его восстановить выбросится исключение ClassNotFoundException.

Ситуация 3: Разорванные нити

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

Что случилось?
При уничтожении процесса останавливаются все его потоки, а при восстановлении запускается только главный поток. Так что если ваш поток работает слишком долго, будьте готовы к тому, что он будет остановлен. Причём не обязательно делать что-то долго, на эти грабли можно наступить и при использовании wait notify. Особенно забавно будет, если в качестве объекта для блокировки использовать public static final Object, ведь мы то уже знаем, что статик объекты не исключение при уничтожении процесса.

Что делать?
Если задача занимает много времени вынести ее в отдельный сервис и запустить в новом процессе, плюс вывести foreground Notification, иначе процесс все равно будет убит. В случае с wait notify все немного сложнее и зависит от конкретной ситуации. Вообще, тема работы с потоками достаточно обширна, и давать какой-то конкретный совет тут неуместно. Разве что не усложнять и не лезть в дебри, из которых не сможешь вылезти.

Ситуация 4: Письмо в никуда

Для того чтобы первая Activity не уничтожалась при поворотах экрана, в файл манифеста добавлены configChanges.

Во второй Activity есть кнопка, нажатие по которой шлет сообщение для смены цвета.

При возвращении на первую Activity цвет View будет изменен.

Что случилось?
Не смотря на то, что стек активностей сохранился, после разворачивания приложения была восстановлена только вторая Activity. Фактически, сообщения о смене цвета уходили в никуда. Так как на тот момент не существовало объектов, подписанных на это событие. При возвращении на первую Activity она была восстановлена, но подписываться на событие смены цвета было уже поздно.

Что делать?
Первым делом нужно уяснить главное — если вы работаете с одной Activity, остальные для нее не существуют. Если нужно донести какую либо информацию, используйте предназначенный для этого setResult. Еще не следует слепо полагаться на жизненные циклы. Как видно из примера, если Activity 1 запустила Activity 2 то это еще не значит, что метод onCreate первой Activity был выполнен.
Также замечу, этот пример показывает не только на проблемы со стеком активностей, но и проблемы со всем, что связано с посылкой сообщений. Исключением будут только BroadcastReceiver-ы, прописанные в манифесте, либо запланированные через AlarmManager. Все остальное не дает 100% гарантии на доставку сообщения адресату.

Заключение

“Бывалым кодерам” эти ситуации могут показаться очевидными, а примеры на столько не естественными, что просто воротит. Однако, все мы когда-то начинали с нуля и писали код от которого сейчас было бы стыдно. Знай я об этих граблях в самом начале своего пути, шишек на лбу было бы меньше. Надеюсь, эта статья поможет наставить на путь истинный большое количество начинающих Android программистов. От “Бывалых” буду рад увидеть комментарии. А еще лучше если вы дополните список или напишете, помогла ли эта статья в ловле багов из разряда “Как?! Такого не может быть!”.

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

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *