UIスレッド(メインスレッド)以外のスレッドからUIを操作したいとき、Windows (.NET)でもAndroid (Java)でも直接操作することは許されない。そういうときはUIスレッドに処理を依頼する形を取る。WindowsならControl.Invoke()またはControl.BeginInvoke()、AndroidならHandler.post()を用いる。
…というのはまあ分かってるのだけども、ふだんC言語ばかり書いているので、たまにC#やJavaを書くと書き方を忘れてしまうのである。
Windows (.NET)
using System.Threading; // フォームのクラス public class FormHoge : Form { // スレッド Thread threadHoge; // スレッド関数 private void threadFunc() { // UIスレッドで実行させる this.Invoke((Action)(() => { // UIの操作 textboxHoge.Text = "hoge"; })); } // スレッド開始 private void startThread() { threadHoge = new Thread(new ThreadStart(threadFunc)); threadHoge.Start(); } }
Android (Java)
- スレッドは、Runnableのrunを実装したものをThreadに渡し、startする。
- UIの操作は、Runnableのrunを実装したものをハンドラにpostする。
import android.os.Handler; // アクティビティのクラス public class HogeActivity extends Activity { // スレッド private Thread mThread; // ハンドラ private Handler mHandler = new Handler(); // スレッド class HogeThread implements Runnable{ public void run() { // UIスレッドで実行させる mHandler.post(new Runnable() { public void run() { // UIの操作 textviewHoge.setText("hoge"); } }); } } // スレッド開始 private void startThread() { mThread = new Thread(new HogeThread()); mThread.start(); } }
※ JavaでもJava8以降 (Androidでは APIレベル24以降)ではRunnableに代えてラムダ式が使えるらしい。