Looper

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

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

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

Работа с Looper включает в себя создание нового объекта Looper для потока, связывание этого Looper с потоком (обычно это делается в методе onCreate() в Activity или в run() в потоке), создание очереди сообщений и обработку сообщений, используя Handler.

import android.os.Handler
import android.os.Looper

class MyLooperThread : Thread() {
    private lateinit var handler: Handler

    override fun run() {
        // Создаем Looper для этого потока
        Looper.prepare()

        // Создаем Handler, связанный с Looper этого потока
        handler = Handler(Looper.myLooper()!!)

        // Запускаем цикл обработки сообщений (message loop)
        Looper.loop()
    }

    fun postTask(task: Runnable) {
        // Постим задачу в очередь сообщений для обработки в Looper
        handler.post(task)
    }
}

fun main() {
    val looperThread = MyLooperThread()
    looperThread.start()

    // Постим задачу в очередь LooperThread
    looperThread.postTask(Runnable {
        println("Выполнение задачи в LooperThread")
    })
}

В этом примере создается собственный поток (MyLooperThread), в котором создается Looper, ассоциированный с этим потоком. Создается также Handler, связанный с этим Looper, для отправки и обработки сообщений в этом потоке.

Looper в контексте обработки нажатий пользователя

Looper в Android используется для обеспечения непрерывности работы пользовательского интерфейса. Когда вы нажимаете на элемент интерфейса, например, кнопку, система генерирует событие нажатия. Это событие ставится в очередь сообщений в потоке UI (главный поток).

Looper в главном потоке UI постоянно выполняет цикл обработки сообщений, извлекая сообщения из очереди и передавая их на обработку. Когда событие нажатия извлекается из очереди, оно обрабатывается соответствующим образом, например, вызывается обработчик события (listener) для кнопки, которая была нажата.

Поскольку Looper в главном потоке UI постоянно работает, приложение может реагировать на нажатия пользователя и другие события интерфейса в реальном времени, не блокируя пользовательский интерфейс.

import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    private lateinit var button: Button

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        button = findViewById(R.id.button)

        // Устанавливаем обработчик нажатия кнопки
        button.setOnClickListener {
            // Постим задачу в очередь главного потока UI для обновления интерфейса
            handler.post {
                // Здесь выполняем код, который должен выполниться при нажатии кнопки
                // Например, изменение текста кнопки или запуск другой активности
                button.text = "Кнопка была нажата"
            }
        }
    }

    companion object {
        private val handler = Handler(Looper.getMainLooper())
    }
}

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