Когда создается Looper

Ответ

Looper создается при вызове Looper.prepare(), обычно в потоке, где требуется обработка сообщений (не UI-потоке). Для главного потока Looper создается автоматически системой при запуске приложения.

Пример создания Looper в фоновом потоке:

Thread {
    Looper.prepare() // Создает Looper для текущего потока
    val handler = Handler(Looper.myLooper()!!)
    Looper.loop() // Запускает цикл обработки сообщений
}.start()

Ключевые моменты:

  • Каждый поток может иметь только один Looper
  • prepare() выбрасывает исключение при повторном вызове
  • loop() блокирует поток до вызова quit()

Ответ 18+ 🔞

А, ну это же классика, ёпта! Смотри, как тут всё устроено, блядь.

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

Создаётся он, когда ты вызываешь Looper.prepare(). Обычно это делаешь прямо в том потоке, где хочешь завести свою собственную очередь сообщений. В главном потоке приложения эта вся хуйня создаётся автоматом, когда система запускает твоё приложение — там париться не надо. А вот в своих потоках — сам, сука, всё делай.

Вот смотри, как это выглядит в коде, тут всё просто:

Thread {
    Looper.prepare() // Вот тут, блядь, создаётся Looper для текущего потока. Всё, приехали.
    val handler = Handler(Looper.myLooper()!!) // А это уже его личный почтальон, который будет таскивать ему сообщения.
    Looper.loop() // И вот это — святое! Запускает цикл обработки. Поток теперь будет сидеть и ждать, пока ему что-то принесут.
}.start()

Теперь ключевые моменты, которые надо запомнить, а то наебнёшься:

  • Каждый поток может иметь только один Looper. Это как почтовое отделение — одно на район. Два не запихнёшь, исключение получишь. prepare() второй раз вызовешь — будет тебе хуй с горы, в смысле, RuntimeException.
  • prepare() — это и есть создание. Вызвал, и всё, Looper привязан к потоку.
  • loop() — это, блядь, вечный двигатель. Он БЛОКИРУЕТ поток и заставляет его крутиться в цикле, выгребая сообщения из очереди. Пока не скажешь quit() — он так и будет висеть. Если его не запустить, то твой Handler будет просто куском бесполезного кода, который нихуя не может.

Короче, схема простая: prepare() -> создаём Handler -> loop(). И не перепутай порядок, а то будет пизда рулю. Всё, теперь твой фоновый поток может общаться с миром через сообщения, как цивилизованный.