UI 関連の処理をおこないたい場合、(Handler クラスのデフォルトコンストラクタを使うと)「UI スレッド内で Handler インスタンスを作成し、Runnable インスタンスを別途作成して当該 Handler インスタンスの post メソッドに渡す」というコーディングが必要で、そのままコーディングすると次のようになるが、
// UI スレッド//// Handler インスタンスを作る。別スレッドで使うというユースケースが// 大半なので、final を付けることが多くなる。final Handler handler = new Handler();
// UI スレッドではない別のスレッド//// UI に関連する処理をスケジュールする。handler.post(new Runnable() {
public void run() {
// UI スレッドで実行する処理を記述する。
}
});
面倒なので、「(1) 常に UI スレッドに紐付けられ、(2) 自クラスで Runnable インターフェースを実装する」Handler クラスのサブクラスを次のように実装してみる。
public class UiHandler extends Handler implements Runnable
{
public UiHandler()
{
// Looper.getMainLooper() で UI スレッドの Looper を取得する。
super(Looper.getMainLooper());
}
public UiHandler(Handler.Callback callback)
{
// Looper.getMainLooper() で UI スレッドの Looper を取得する。
super(Looper.getMainLooper(), callback);
}
public boolean post()
{
// 自分で Runnable インターフェースを実装しているので、// post メソッドに this を渡すことができる。return post(this);
}
public boolean postAtFrontOfQueue()
{
return postAtFrontOfQueue(this);
}
public boolean postAtTime(Object token, long uptimeMillis)
{
return postAtTime(this, token, uptimeMillis);
}
public boolean postAtTime(long uptimeMillis)
{
return postAtTime(this, uptimeMillis);
}
public boolean postDelayed(long delayMillis)
{
return postDelayed(this, delayMillis);
}
public void run()
{
// UI スレッドで実行する処理を記述する。// サブクラスでオーバーライドすべき。}
}
これにより、「任意のスレッド内で」(←面倒削減ポイント)当該サブクラスのインスタンスを作成できる上、Handler と Runnable を別々に管理する必要もなくなり、下記のようなコーディングが可能となる。
new UiHandler() {
public void run() {
// UI スレッドで実行する処理を記述する。
}
}.post();