Android

【Java】Handlerクラスについてまとめてみました

投稿日:2019年12月19日 更新日:

はじめに

こんにちは、matsunariです。今回はHanderクラスについて勉強しましたのでまとめたいと思います。

Handlerクラスを使う理由

Android アプリでスレッド処理を行いたい場合、注意が必要なのが別のスレッドから直接アプリのUIに関する操作を行うことはできません。
なぜこのような制限があるのでしょうか?

例えば、メインスレッドでないスレッドが並列で実行されているときに、メインスレッドとそれ以外のスレッドが同時に同じテキストビューにsetText()を試みる場合です。

このような場合、2つのうちどちらのスレッドのsetText()が適用されるかは予測できず、ユーザは2つのうち1つの値しか見ることができません。

このように2つ以上のスレッドを使用する際の同期問題を解消するためにLooperHandlerを使います。
(ちなみに別のスレッドから直接UI操作の処理を行おうとすると、Called from Wrong Thread Exceptionというエラーが発生します。)

Handlerクラスの基本

Handlerクラスを使う前にどのような仕組みで動作しているのか確認してみましょう。

実はUIを管理するメインスレッドでは、内部的にLooper というオブジェクトを持っています。さらにその中にMessageQueueを含んでいます。MessageQueueとはコレクションフレームワークのQueueの一種のことです。(備考:Queueは入れた順番が古いものから処理されるFirst In First Outの性質があります)。
LooperMessageRunnableオブジェクトを順番に取り出しHandlerが処理するように伝えます。Messageはスレッド間通信する内容を盛り込んだオブジェクトのことです。

HandlerはLooperから受けたMessageを実行、処理したり、Looperの持つMessageQueueに送信するための装置のようなものだと考えると良いでしょう。

Handlerを使ってsetText()を実行してみる

実際にHandlerを使ったサンプルを確認してみましょう。

このサンプルを実行すると次のような結果を得ることができます。

重要なポイントは、post()メソッドはhandlerインスタンスを生成したスレッドにrunnableオブジェクトを送るというところです。今回のケースでは、メインスレッドでhandlerインスタンスが生成されているためメインスレッドのUIは問題なく変化しました。これを別スレッドで行なったとしても効果はありません。実行するスレッドに注意が必要です。

sendMessage()を実行してみる

今度は冒頭にも少し説明したMessageオブジェクトを使ったサンプルを見てみましょう。

上記サンプルコードではsendMessageメソッドを使用しています。sendMessageメソッドを使うことで、引数にMessageオブジェクトを指定して、情報をhandleMessageメソッドに渡す事ができます。Messageクラスのプロパティに関しては以下の通りです。

◼️int what
メッセージの識別子として使う事を目的とした、ユーザが勝手に定義して使う事のできる値のこと。
◼️int arg1,int arg2
whatの他に、arg1とarg2に指定した2つの整数値を渡す事ができる。
◼️Object obj
オブジェクトを渡したい場合は、この変数に代入する事ができる。

サンプルコードを実行するとこのような結果になりました。

出力したログ

さいごに

今回は前回投稿のスレッドに続いてHandlerについてまとめてみました。Handler自体の役割は比較的理解しやすい感じはありましたが、仕組みまで覗いてみると深い内容だったので調べ甲斐がありました。またこの他にもスレッドに関係する機能について深掘りを進めていきたいと思っています。

おすすめ書籍

スッキリわかるJava入門 第3版 (スッキリシリーズ) スッキリわかる Java入門 実践編 第2版 (スッキリシリーズ) AndroidエンジニアのためのモダンJava

blog-page_footer_336




blog-page_footer_336




-Android
-,

執筆者:

免責事項

このブログは、記事上部に記載のある投稿日時点の一般的な情報を提供するものであり、投資等の勧誘・法的・税務上の助言を提供するものではありません。仮想通貨の投資・損益計算は複雑であり、個々の取引状況や法律の変更によって異なる可能性があります。ブログに記載された情報は参考程度のものであり、特定の状況に基づいた行動の決定には専門家の助言を求めることをお勧めします。当ブログの情報に基づいた行動に関連して生じた損失やリスクについて、筆者は責任を負いかねます。最新の法律や税務情報を確認し、必要に応じて専門家に相談することをお勧めします。


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


関連記事

[Android] リソースフォルダの修飾子

1 はじめに2 画面の向き3 画面サイズ4 テキスト入力方法5 複数修飾子の組み合わせ6 その他7 さいごに はじめに Androidアプリではリソースフォルダ名に修飾子をつけることによって、様々な環 ...

Flutterでテストコードを書こう! 単体テスト・Widgetテスト・インテグレーションテスト

1 はじめに2 単体テスト2.1 testパッケージの利用2.2 テストの書き方2.3 テストの実行2.4 モック化2.4.1 mockitoの導入2.4.2 メソッドのモック化3 Widgetテスト ...

Android Studioでエラーログを詳細表示する

1 はじめに2 初期設定でのビルドエラーメッセージ3 詳細なビルドエラーメッセージを出力4 おまけ5 さいごに6 おすすめ書籍 はじめに こんにちは。Android開発を久しぶりにやっているのですが、 ...

KotlinでAndroidの双方向DataBindingを利用する

1 はじめに2 MVVMアーキテクチャ2.1 Model2.2 View2.3 ViewModel3 KotlinでAndroid DataBindingを設定4 説明用のサンプルアプリについて5 a ...

[Android] パーミッション管理を簡単・簡潔に書けそうなPermissionsDispatcher

1 はじめに2 環境3 導入4 Activityでの実装例5 @RuntimePermissions(必須)6 PermissionsDispatcherに処理を移譲する7 @NeedsPermiss ...

フォロー

blog-page_side_responsive

2019年12月
1234567
891011121314
15161718192021
22232425262728
293031  

アプリ情報

私たちは無料アプリもリリースしています、ぜひご覧ください。 下記のアイコンから無料でダウンロードできます。