Программирование приложений для мобильных устройств под управлением Android. Часть 2
И мы будем использовать сообщения, когда поток-отправитель указывает какую операцию необходимо выполнить в другом потоке, а как её выполнить определит handler.
В Android каждый поток связан с очередью сообщений – messageQueue и петлителем – Looper. Очередь сообщений – структура данных, которая содержит сообщения и объекты runnable. Петлитель забирает эти сообщения и объекты runnable из очереди сообщений и диспетчеризирует их в зависимости от обстоятельств.
Эта диаграмма изображает поток Tread A, который создает Runnable внутри метода post (опубликовать) и использует объект-обработчик – Handler, чтобы отправить его в поток этого обработчика. Runnable помещается в очередь сообщений потока, связанного с обработчиком. И тоже самое происходит с сообщениями.
А эта диаграмма изображает поток Thread B, который создает сообщение и использует метод обработчика sendMessage, чтобы отправить это сообщение в поток обработчика. Сообщение помещается в очередь сообщений, связанную с этим обработчиком.
В то время, когда выполняются все вышеописанные операции, объект-петлитель просто «сидит» ожидая работы, которая появится в очереди сообщений. И когда эта работа появляется, петлитель реагирует одним из двух способов в зависимости от вида работы, которая только что появилась. Если эта работа – сообщение, петлитель обрабатывает это сообщение, вызывая метод обработчика handleMessage и передавая в нем само сообщение. Если же эта работа будет Runnable, то петлитель просто вызывает его метод run.
Существует несколько методов, которые позволяют запланировать выполнение работы в разное время. Например, можно использовать метод postAtTime, чтобы добавить runnable в очередь сообщений и выполнить его в определенное вами время. Метод postDelayed позволяет добавить runnable в очередь сообщений и выполнить его после указанной задержки.
Если вы хотите отправлять сообщения, сначала необходимо сообщение создать. Один из способов это сделать – использовать метод обработчика obtainMessage, который выдаст вам сообщение уже с установленным обработчиком. Можно также использовать метод obtain класса message.
Что касается runnable, то есть несколько методов, которые можно использовать, чтобы отправить сообщение. Метод sendMessage уже упоминался. Есть также его версия, которая позволяет поместить сообщение вперед в очереди сообщений, чтобы оно было выполнено как можно скорее. Есть метод sendMessageAtTime, чтобы поставить сообщение в очередь согласно требуемому времени. Есть также метод sendMessageDelayed, который поставит сообщение в очередь в текущее время плюс указанная задержка.
Давайте рассмотрим исходный код некоторых версий нашего рабочего примера, в котором были использованы обработчики. Вот приложение Threading handler runnable. Откроем основную Activity этого приложения. Во-первых, вы видите, что этот код создает новый обработчик. Этот обработчик создается в основном потоке пользовательского интерфейса. Таким образом, объекты runnable, которые получает этот обработчик, будут выполняться в UI потоке.
Далее вы