11645


Handler.post()へ受け渡すRunnableオブジェクトは、よく匿名クラスとして受け渡すように記述されている事が多いと思います。

[code]

    mHandler.post(new Runnable() {
        @Override
        public void run() {
    
        }
    });
    
[/code]

しかし例えば、この処理を呼び出す頻度が非常に高い場合、毎回新たにRunnableオブジェクトを作りたくありません。

そこで以下のようにオブジェクトを使い回して、例えばtest1()が呼ばれた時とtest2()が呼ばれた時とで表示したい文字列だけを上書きするようにした場合、まだHandler側でまだ処理されていない文字列が上書きされて消えてしまう等の問題が発生するものでしょうか。  
このような使い方は正しいのでしょうか、教えて頂けると助かります。

[code]

    private class TestRunnable implements Runnable {
        private String mMessage;
    
        public TestRunnable setStr(final String message) {
            mMessage = message;
            return this;
        }
    
        @Override
        public void run() {
            Log.d("Test", "Message:" + mMessage);
        }
    }
    
    private Handler mHandler = new Handler();
    private TestRunnable mTestRunnable = new TestRunnable();
    
    public void test1(String msg) {
        mHandler.post(mTestRunnable.setStr(msg));
    }
    
    public void test2(String msg) {
        mHandler.post(mTestRunnable.setStr(msg));
    }
    
[/code]


CC BY-SA 3.0
2015-06-23T09:07:20.737
11640
2015-06-23T12:02:39.253
4232
question
android java
Handler.post()へ受け渡すRunnableオブジェクトを使い回しても良いでしょうか


OS としては大丈夫そうですが、例に上げられているそのソースコードでは意図通りに動かない可能性が高いです。

まず「OS
としては大丈夫」とした根拠ですが、[Handler.javaのソースコード](https://android.googlesource.com/platform/frameworks/base/+/android-5.1.1_r4/core/java/android/os/Handler.java#324)
を追うことでわかります。 細部は省略しますが、`Handler#post()` では引数の `Runnable` を `Message`
でラップしてキューに追加します。よって仮に1つの `Runnable` インスタンスを複数回渡しても、それぞれが別の `Message`
として解釈され、呼び出されると推定できます。

しかしながら例に上げられたコードでは、`test1()` 呼出し後に `mTestRunnable#run()` が実行される前に `test2()`
が呼び出されてしまうと、`mTestRunnable#mMessage` が更新されてしまい、
意図せぬ実行結果(同じメッセージ/テキストが2度処理される)になると推測されます。

以上をまとめますと、`Handler#post()`
には同じインスタンスを複数回渡すことができますが、だいたいの場合その「インスタンスが再入可能であること」が必須といえるでしょう。あと、どうしても再入不可能なまま再利用をするのであれば、オブジェクトプールを使うなどの手段も考えられます。なお
`Message` はこのオブジェクトプールを使う実装になっていましたので、興味があれば一度読まれることをオススメしておきます。

個人的には毎回作成することを推奨いたします。ヘタに凝るとわかりにくいバグになりそうですから。


CC BY-SA 3.0
2015-06-23T11:57:27.393
11645
2015-06-23T12:02:39.253
2015-06-23T12:02:39.253
208
208
11640
answer