kotlin_Handlerとは? executor_worker_Looperとの違い

 


android開発で スレッドを扱う際に出てくる用語に

Handlerというものもあるようですが、


これは どのような役割があるんでしょうか?





Android開発で使われる **`Handler`** は、

スレッド間でメッセージを送受信したり、

UIスレッド(メインスレッド)で特定の処理を実行する際に役立つクラスです。

特に、非同期処理でスレッドを操作するときに重要な役割を果たします。



### 主な役割


1. **スレッド間の通信**  


   - Androidでは、UIの更新は必ずメインスレッド(UIスレッド)で行う必要があります。



   - ワーカー(バックグラウンド)スレッドで処理を実行した後、

その結果をUIスレッドに通知するために `Handler` を使用します。



2. **メッセージのキューイングと処理**  


   - `Handler` はメッセージキュー(`MessageQueue`)を管理します。

`Message` または `Runnable` をメッセージキューに追加し、

それを処理することができます。



   - メッセージを遅延実行したり、

特定のタイミングで処理をスケジュールすることが可能です。



3. **非同期処理のスケジューリング**  


   - 特定のコードを遅延させたり、繰り返し実行する場合に利用できます。


---



### 具体的な使い方



#### 1. メインスレッドでのUI更新


例えば、バックグラウンドスレッドでデータを処理して、結果をUIに反映する場合:


```kotlin


val handler = Handler(Looper.getMainLooper())



Thread {


    val result = "処理結果"

    // メインスレッドでUIを更新


    handler.post {

        textView.text = result

    }


}.start()


```


- `Looper.getMainLooper()` を渡して、

メインスレッドのメッセージループに紐づけられた `Handler` を作成します。



- `handler.post {}` 内のコードはメインスレッドで実行されます。


---


#### 2. メッセージの送受信


メッセージキューにメッセージを送信して、それを別のスレッドで処理する例です。


```kotlin


val handler = object : Handler(Looper.getMainLooper()) {


    override fun handleMessage(msg: Message) {


        // メッセージを処理

        textView.text = msg.obj as String


    }


}



Thread {


    val message = Message.obtain()

    message.obj = "バックグラウンド処理が完了しました"

    handler.sendMessage(message)


}.start()



```


- `sendMessage()` を使って、スレッド間でメッセージを送受信します。


- `handleMessage()` メソッド内で、受信したメッセージを処理します。


---


### 注意点


- **`Handler` のメモリリーク問題**: 


`Handler` が長期間にわたり非同期タスクを保持している場合、

親コンポーネント(`Activity` など)が破棄されても解放されない可能性があります。

これを防ぐために、`Handler` を静的にするか、弱参照を使うべきです。



---


### 代替案: `Handler` 以外の選択肢


最近のAndroid開発では、

`Handler` よりも以下のAPIを使うことが一般的です。



1. **`HandlerThread`**


   - 専用のバックグラウンドスレッドと `Handler` を組み合わせて使用します。

   

   

2. **`Executors`** / **`ThreadPoolExecutor`**


   - マルチスレッド処理の管理に適しています。


3. **`LiveData`** / **`ViewModel`**


   - UIスレッドでのデータ更新をより簡潔に行えます。



4. **`Coroutine`(Kotlin)**


   - コルーチンは非同期処理を直感的に記述でき、

`Handler` の代替としても優れています。



例えば、上記のUI更新は次のように書き換えられます:



```kotlin


GlobalScope.launch(Dispatchers.Main) {


    val result = withContext(Dispatchers.IO) {

        "処理結果"

    }

    textView.text = result

}


```


---


**まとめ**  


`Handler` はスレッド間での通信や非同期タスクのスケジューリングに

便利なクラスですが、

現在ではよりモダンな方法

(例えばコルーチンや`LiveData`)が推奨される場合も多いです。


ただし、低レベルのスレッド操作が必要な場合には依然として有用です。


コメント