(メモ書き)AndroidのHandlerとHandlerThreadで情報の同期

古くからある、AndroidのHandlerとHandlerThreadについて、動作を検証する。

いわゆる、自分用メモ(必要に応じ、近時の非同期ライブラリなども随時追記していく)。
   
#1.メッセージをあるところで同期したい。
   
素のJavaでのThreadを扱う時には、Thread間のメッセージの同期はThread#join()メソッドを使って行う。同じようなことをAndroidのDialog表示において、標準ライブラリのみを活用して行いたい。
   
素のJavaでのメインスレッドと新スレッドとの間のメッセージのやり取りは、こんな感じ。
   
```.java
    class Main {
    public static void main(String[] args) {
        System.out.println(Thread.currentThread() + ": Start. (A)");
        try {
            Thread th = new Thread() {
                public void run() {
                    try {
                        System.out.println(Thread.currentThread() + ": Start. (B)");
                        for (int i = 0; i < 20; i++) {
                            System.out.println(this + ": i = " + i);
                            Thread.sleep(10);
                        }
                        System.out.println(Thread.currentThread() + ": End. (B)");
                    } catch (InterruptedException e) {
                        System.out.println(e);
                    }
                }
            };
            th.start();
            System.out.println(Thread.currentThread() + ": Start2. (A)");
            Thread.sleep(20);
            System.out.println(Thread.currentThread() + ": Cont. (A)");
            
            th.join();　//**ここで同期**
            
            System.out.println(Thread.currentThread() + ": 同期後①. (A)");
        } catch (InterruptedException e) {
            System.out.println(e);
        }
        System.out.println(Thread.currentThread() + ": 同期後②. (A)");
    }
}
```

実行結果

```
Thread[main,5,main]: Start. (A)
Thread[main,5,main]: Start2. (A)
Thread[Thread-0,5,main]: Start. (B)
Thread[Thread-0,5,main]: i = 0
Thread[Thread-0,5,main]: i = 1
Thread[Thread-0,5,main]: i = 2
Thread[main,5,main]: Cont. (A)
Thread[Thread-0,5,main]: i = 3
Thread[Thread-0,5,main]: i = 4
Thread[Thread-0,5,main]: i = 5
Thread[Thread-0,5,main]: i = 6
Thread[Thread-0,5,main]: i = 7
Thread[Thread-0,5,main]: i = 8
Thread[Thread-0,5,main]: i = 9
Thread[Thread-0,5,main]: i = 10
Thread[Thread-0,5,main]: i = 11
Thread[Thread-0,5,main]: i = 12
Thread[Thread-0,5,main]: i = 13
Thread[Thread-0,5,main]: i = 14
Thread[Thread-0,5,main]: i = 15
Thread[Thread-0,5,main]: i = 16
Thread[Thread-0,5,main]: i = 17
Thread[Thread-0,5,main]: i = 18
Thread[Thread-0,5,main]: i = 19
Thread[Thread-0,5,main]: End. (B)
Thread[main,5,main]:  同期後①. (A)
Thread[main,5,main]: 同期後②. (A)
```

参考 Javaのjoinメソッド
http://d.hatena.ne.jp/hyuki/20090222/java

#2 AndroidのActivityなどで情報の同期

Androidで、カメラでのQRコード読取結果をあるところで取得する、メッセージダイアログの選択結果をあるところで取得するといった場合も、Threadクラスを拡張したHandlerThreadが使えるはず。
##注、非同期系の便利ライブラリは一旦忘れる。

参考　Androidのカメラ関係のメソッドを非同期で実行したい
http://serenegiant.com/blog/?p=51

出発点としては、
別スレッドでキュー管理(Handler, Looper, HandlerThread)
http://daichan4649.hatenablog.jp/entry/20111004/1317724067

で書かれている以下のあたりが参考になる。

```.java

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    
    // 新スレ生成 -> 開始
    HandlerThread handlerThread = new HandlerThread("other");
    handlerThread.start();

    // HandlerがhandlerThreadのLooperを取得。
    Handler handler = new Handler(handlerThread.getLooper());
    handler.post(new Runnable() {
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName());
        }
    });
}
```

スレッド名"other"があるタイミングで取得できることは分かる。では、取得タイミングをどう制御するのか。

HandlerとLooperが登場する。
参考
http://mixi-inc.github.io/AndroidTraining/fundamentals/2.12.handler-and-looper.html

>メインスレッド用のLooperを取得する場合は以下のようにします。
>Looper looper = Looper.getMainLooper();
...
>Looperに対してメッセージを送る役割を担っているのがHandlerです。...メインスレッドの Looper にメッセージを送るHandlerインスタンスを生成する場合は、以下のようにします。
> Handler handler = new Handler(Looper.getMainLooper());

参考
https://realm.io/jp/news/android-thread-looper-handler/

#3 お題。アラートダイアログの選択結果を、あるタイミングで取得したい

コピペしてすぐ使えるアラートダイアログ集
http://qiita.com/suzukihr/items/8973527ebb8bb35f6bb8
などを参考に、各種ダイアログでの選択結果をHandlerとHandlerThreadとで扱いたい。

```
(ダイアログを生成する呼び出し元でしたいこと)

            HandlerThread th = new HandlerThread() {
                public void run() {
                    try {
                        ここで、ダイアログからの「選択結果」を待つ(数秒間を想定)
                        }
                    } catch (InterruptedException e) {
                        System.out.println(e);
                    }
                }
            };

(別スレッドのダイアログ側でしたいこと)

ダイアログからの「選択結果」(例Yes or No)をセットする。

```


さて、どう書くか。本日のお題としておく。
回答は後ほど。

#4(絶対)落ちないアプリ?

話はここで終わらない。というか、ここからが出発点

参考　絶対落ちないアプリの作り方
http://www.slideshare.net/fumihikoshiroyama/ss-47472394

>非同期処理はコントローラよ り寿命が長いことがままある...Activityより長生き… ここにクラシュの罠がたくさんある

こちらが次のお題。