tgoop.com/dev_easy_notes/150
Last Update:
Итак, я наконец-то добрался до того, чтобы уже сделать предпоследний пост этой серии. Сейчас вы узнаете каким образом дергаются методы ЖЦ все ваших Activity.
Существует куча различных кейсов, как меняются ЖЦ Activity, вот например некоторые из них:
👉 Старт первой Activity
👉 Запуск новой Activity поверх старой
👉 Переворот Activity
👉 Уничтожение предыдущих Activity из-за нехватки памяти
👉 Запуск Activity другого приложение поверх наших Activity
Прикол в том, что для каждого из этих кейсов используются свои сервисы и свои подходы вычисления когда нужно вызывать методы ЖЦ. Если разбирать каждый такой кейс, получится дипломная работа, да и вам эта информация ничего не даст. В посте мы разберем лишь кейс со стартом первой Activity и общий подход как система в целом дергает методы ЖЦ без разбора того, как она понимает когда нужно дернуть методы.
Когда я первый раз увидел код приложения под Android, я был в недоумении, а где же метод main? Все казалось какой-то магией, мы создаем Activity у которых когда-то будут вызваны методы. На самом деле метод main есть и его довольно легко найти. Он находится в классе ActivityThread
. ActivityThread
это основной поток нашего приложения, тот самый поток в котором работает главный Looper. В ActivityThread
сокрыто куча всего, всяких настроек и т.д, но нас сейчас интересует лишь старт Activity.
В предыдущем посте мы обсудили, как запускается процесс нашего приложения. Вот что происходит далее, в начале запускается статичный метод main
. В этом методе инициализируется главный Looper и после этого дергается метод bindApplication
через IPC у ActivityManagerService
. Этим мы сообщаем сервису, что вот мы стартанули приложения и нам сейчас нужна помощь с Activity. Далее ActivityManagerService
производит свою магию и дергает уже наш метод ActivityT
hread
, т.к при вызове метода bindApplication
мы передали объект нашего ActivityTread
.
После того как ActivityManagerService
дернул наш метод, ActivityT
hread
отправляет сообщение BIND_APPLICATION
в очередь Looper
и запускает этот самый Looper
. На этом моменте выполнение метода main прекращается, т.к запустился бесконечный цикл Looper. Далее Looper главного потока выполняет сообщения BIND_APPLICATION
которое просто вызывает еще один метод для настройки и дальше ничего не происходит потому как в Looper главного потока больше нет сообщений.
Пока главный поток настраивался, ActivityManagerService
подготавливал первую Activity к запуску. Как именно он это делает: на основе информации полученной из ActivityThread
ActivityManagerService
знает о том, какую Activity нужно запустить. Однако он не создает саму Activity, у него лишь есть информация о том, что это за Activity и как ее нужно запустить. Затем он создает специальный объект, этот объект транзакция, в котором есть вся информация перечисленная выше. Этот объект отправляется через IPC в главный Looper нашего приложения.
Сообщения транзакции представлены в виде специального сообщения. Как вы знаете можно при помощи специальных колбэков в Handler перехватывать нужные нам сообщения. В нашем приложении есть такой объект как TransactionExecutor
, он и перехватывает эти сообщения и затем выполняет.
В переданной транзакции есть информация о том, какой метод ЖЦ какой Activity нужно вызвать. Информация эта представлена специальным объектом, который описывает статус ЖЦ Activity. Если говорить конкретно, то там есть специальный класс наследники которого так и называются OnCreateActivityItem
, OnStartActivityItem
и т.д. Получив транзакцию TransactionExecutor
дергает нужные методы.
По сути это все, в системе есть куча различных сервисов, которые знают о наших Activity и решают у какой Activity какой ЖЦ вызывать. И вызывают они методы ЖЦ через транзакции послание через Binder. Часть транзакции приходят из вне, часть же транзакции создает наше же приложение, например когда одна Activity перекрывает другую. Транзакцию с методом onStop создает сам ActivityThread
.
BY Dev Easy Notes
Share with your friend now:
tgoop.com/dev_easy_notes/150