← Назад к вопросам

Где запускается Looper?

1.8 Middle🔥 171 комментариев
#Android компоненты#Многопоточность и асинхронность

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Где запускается Looper в Android?

Looper в Android запускается автоматически в главном потоке приложения (UI-потоке), но для фоновых потоков его необходимо создавать и запускать вручную.

Looper в главном потоке (UI-потоке)

При запуске Android-приложения система автоматически создает и запускает Looper для главного потока. Это происходит в методе ActivityThread.main(), который является точкой входа для каждого Android-приложения:

// Упрощенный код из Android Framework
public final class ActivityThread {
    public static void main(String[] args) {
        Looper.prepareMainLooper(); // Подготовка главного Looper'а
        Looper.loop(); // Запуск бесконечного цикла обработки сообщений
    }
}

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

  • Looper.prepareMainLooper() – создает Looper для главного потока
  • Looper.loop() – запускает цикл обработки сообщений

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

Lopper в фоновых потоках

Для создания фонового потока с возможностью обработки асинхронных задач (например, для HandlerThread или кастомных рабочих потоков) необходимо явно вызвать:

// Создание Looper'а в фоновом потоке
class WorkerThread : Thread() {
    lateinit var handler: Handler
    
    override fun run() {
        Looper.prepare() // 1. Подготовка Looper'а для текущего потока
        
        handler = Handler(Looper.myLooper()!!) { msg ->
            // Обработка сообщений
            when (msg.what) {
                TASK_1 -> performTask1()
                TASK_2 -> performTask2()
            }
            true
        }
        
        Looper.loop() // 2. Запуск цикла обработки
    }
    
    fun performTask1() {
        // Выполнение задачи
    }
}

Практическое применение

Типичные сценарии использования Looper:

  1. HandlerThread – готовый класс, который уже содержит запущенный Looper:
val handlerThread = HandlerThread("MyWorkerThread")
handlerThread.start()
val handler = Handler(handlerThread.looper)
  1. Взаимодействие между потоками через Handler:
// В фоновом потоке
backgroundHandler.post {
    // Выполнение задачи в фоновом потоке
    val result = performHeavyCalculation()
    
    // Отправка результата в UI-поток
    mainHandler.post {
        updateUI(result)
    }
}
  1. Создание кастомных Looper'ов для обработки последовательных задач.

Критические нюансы

  • Главный Looper нельзя остановить – вызов Looper.quit() приведет к исключению
  • Фоновые Looper'ы должны явно останавливаться через Looper.quitSafely() для избежания утечек памяти
  • Каждый поток может иметь только один Looper, который должен быть подготовлен перед созданием Handler'а
  • Попытка создать Handler без Looper'а вызовет RuntimeException с сообщением "Can't create handler inside thread that has not called Looper.prepare()"

Заключение

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