Поговорим о потоках, хэндлерах, очереди сообщений и как они связаны.

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

Message — сообщение представляет собой контейнер для набора инструкций, которые будут выполнены в другом Thread-e.

MessageQueue — класс низкого уровня, содержащий список сообщений. Позволяет перекидывать данные из одного потока в другой. В такую очередь можно добавлять задания из других потоков, заданиями могут быть переменные, объекты или кусок кода для исполнения (Runnable).

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

Handler — класс который позволяет взаимодействовать с Looper-ом. С помощью Handler-а можно отправить Message, через реализацию интерфейса Runnable, в Looper. Message будет Thread-ом с которым связан сразу или через некоторое время. Привязка между Handler-ом и целевым Thread-ом(например MainThread) достигается с помощью Looper и MessageQueue. A Handler всегда привязан к a Looper-у, а затем привязан к Thread-у, связанному с Looper-ом. В отличие от Looper-а, несколько экземпляров Handler-а могут быть привязаны к одному и тому же Thread-у. Всякий раз, когда мы вызываем post()  или любые подобные методы, новый Message добавляется к связанному MessageQueue. Когда вы создаете новый Handler, он привязан к  Thread-у, который его создает. Он будет доставлять Message-ы и Runnables в MessageQueue и выполнять их при выходе из MessageQueue.

Looper — реализует бесконечный цикл обработки сообщений. Looper преобразует нормальный Thread, который заканчивается, когда возвращается его метод run(), в то, что работает непрерывно до тех пор, пока приложение Android не будет завершено.  Looper предоставляет MessageQueue, который необходим в графическом интерфейсе. Каждый Looper уникален для каждого Thread-a. Чтобы гарантировать эту ассоциацию, Looper хранится в потоковом локальном хранилище и не может быть создан через его конструктор напрямую.

А теперь вернемся к Основному потоку.

Известный нам Main Thread является по сути Looper Thread-ом. Так как, Looper позволяет работать Thread-у бесконечно до тех пор пока не будет уничтожен закрытием приложения. MainThread очень важен, так как он отвечает за диспетчеризацию событий на виджеты соответствующего интерфейса пользователя, включая события графического представления. Он также является потоком, в котором приложение взаимодействует с компонентами из набора инструментов пользовательского интерфейса Android (компонентами из пакетов android.widget и android.view). По существу, главный поток — это то, что иногда называют потоком пользовательского интерфейса(UI Thread).