В этом уроке:

- посылаем простейшее сообщение для Handler

 

Надеюсь, вы прониклись предыдущим уроком и осознали, какая полезная штука Handler. Мы там отправляли ему сообщение. Сегодня сделаем это еще раз, но уже без кучи лишнего кода, зависающих экранов и ошибок приложения. Этакий чистый пример, чтобы закрепить.

 

Как мы помним, Handler позволяет класть в очередь сообщения и сам же умеет их обрабатывать. Фишка тут в том, что положить сообщение он может из одного потока, а прочесть из другого.

Сообщение может содержать в себе атрибуты. Сегодня рассмотрим самый простой вариант, атрибут what.

Напишем простое приложение-клиент. Оно, как-будто, будет подключаться к серверу, выполнять какую-то работу и отключаться. На экране мы будем наблюдать, как меняется статус подключения и как крутится ProgressBar при подключении.

При сменах состояния подключения мы будем отправлять сообщение для Handler. А в атрибут what будем класть текущий статус. Handler при обработке сообщения прочтет из него what и выполнит какие-либо действия.

 

Создадим проект:

Project name: P0811_ HandlerSimpleMessage
Build Target: Android 2.3.3
Application name: HandlerSimpleMessage
Package name: ru.startandroid.develop.p0811handlersimplemessage
Create Activity: MainActivity

 

strings.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
	<string name="app_name">HandlerSimpleMessage</string>
	<string name="connect">Connect</string>
</resources>

 

main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent"
	android:orientation="vertical">
	<Button
		android:id="@+id/btnConnect"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:onClick="onclick"
		android:text="@string/connect">
	</Button>
	<TextView
		android:id="@+id/tvStatus"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:text="">
	</TextView>
	<ProgressBar
		android:id="@+id/pbConnect"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:indeterminate="true"
		android:visibility="gone">
	</ProgressBar>
</LinearLayout>

Кнопка для старта подключения, TextView для вывода информации о статусе подключения и ProgressBar, работающий в процессе подключения.

 

MainActivity.java:

package ru.startandroid.develop.p0811handlersimplemessage;

import java.util.concurrent.TimeUnit;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

public class MainActivity extends Activity {

  final String LOG_TAG = "myLogs";

  final int STATUS_NONE = 0; // нет подключения
  final int STATUS_CONNECTING = 1; // подключаемся
  final int STATUS_CONNECTED = 2; // подключено

  Handler h;

  TextView tvStatus;
  ProgressBar pbConnect;
  Button btnConnect;

  /** Called when the activity is first created. */
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    tvStatus = (TextView) findViewById(R.id.tvStatus);
    pbConnect = (ProgressBar) findViewById(R.id.pbConnect);
    btnConnect = (Button) findViewById(R.id.btnConnect);

    h = new Handler() {
      public void handleMessage(android.os.Message msg) {
        switch (msg.what) {
        case STATUS_NONE:
          btnConnect.setEnabled(true);
          tvStatus.setText("Not connected");
          break;
        case STATUS_CONNECTING:
          btnConnect.setEnabled(false);
          pbConnect.setVisibility(View.VISIBLE);
          tvStatus.setText("Connecting");
          break;
        case STATUS_CONNECTED:
          pbConnect.setVisibility(View.GONE);
          tvStatus.setText("Connected");
          break;
        }
      };
    };
    h.sendEmptyMessage(STATUS_NONE);
  }

  public void onclick(View v) {
    Thread t = new Thread(new Runnable() {
      public void run() {
        try {
          // устанавливаем подключение
          h.sendEmptyMessage(STATUS_CONNECTING);
          TimeUnit.SECONDS.sleep(2);

          // установлено
          h.sendEmptyMessage(STATUS_CONNECTED);

          // выполняется какая-то работа
          TimeUnit.SECONDS.sleep(3);

          // разрываем подключение
          h.sendEmptyMessage(STATUS_NONE);

        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    });
    t.start();
  }

}

STATUS_NONE, STATUS_CONNECTING, STATUS_CONNECTED – это константы статуса. Их будем передавать в сообщении, в атрибуте what. Разумеется, названия и значения этих констант произвольны и взяты из головы. Вы можете придумать и использовать свои.

В onCreate мы создаем Handler и реализуем его метод handleMessage. Этот метод отвечает за обработку сообщений, которые предназначены для этого Handler. Соответственно на вход метода идет сообщение – Message. Мы читаем атрибут what и в зависимости от статуса подключения меняем экран:

STATUS_NONE – нет подключения. Кнопка подключения активна, TextView отражает статус подключения.

STATUS_CONNECTING – в процессе подключения. Кнопка подключения неактивна, показываем ProgressBar, TextView отражает статус подключения.

STATUS_CONNECTED – подключено. Скрываем ProgressBar, TextView отражает статус подключения.

В onCreate после создания Handler мы сразу отправляем ему сообщение со статусом STATUS_NONE. Для этого мы используем метод sendEmptyMessage. В этом методе создается сообщение, заполняется его атрибут what (значением, которое мы передаем в sendEmptyMessage), устанавливается Handler в качестве адресата и сообщение отправляется в очередь.

 

В методе onclick мы создаем и запускаем новый поток. В нем мы, с помощью sleep, эмулируем процесс подключения к серверу, выполнение работы и отключение. И, по мере выполнения действий, отправляем сообщения со статусами для Handler. Т.е. получается, что после нажатия на кнопку Connect статус меняется на STATUS_CONNECTING, две секунды идет подключение, статус меняется на STATUS_CONNECTED, 3 секунды выполняются действия и статус меняется на STATUS_NONE. Давайте проверим.

 

Все сохраним и запустим приложение.

Жмем Connect.

Подключение пошло. Появляется ProgressBar, меняется текст и неактивна кнопка Connect.

Проходит две секунды.

Подключение установлено. ProgressBar исчезает и меняется текст.

Проходит еще 3 секунды.

Подключение завершается. Кнопка Connect снова активна, а текст показывает, что мы не подключены.

 

Т.е. для простого обновления статуса из нового потока нам хватило атрибута what. Но кроме what сообщение может иметь еще несколько атрибутов. Рассмотрим их на следующем уроке.

 

На следующем уроке:

- создаем более содержательные сообщения для Handler


Присоединяйтесь к нам в Telegram:

- в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

- в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Compose, Kotlin, RxJava, Dagger, Тестирование, Performance 

- ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня




Language

Автор сайта

Дмитрий Виноградов

Подробнее можно посмотреть или почитать.

Никакие другие люди не имеют к этому сайту никакого отношения и просто занимаются плагиатом.

Социальные сети

 

В канале я публикую ссылки на интересные и полезные статьи по Android

В чате можно обсудить вопросы и проблемы, возникающие при разработке



Группа ВКонтакте



Поддержка проекта

Яндекс
410011180491924

WebMoney
R248743991365
Z551306702056

Paypal