52

他のスレッドから GUI を更新するには、基本的に 2 つの主な方法があります。

  1. 次のいずれかの方法で java.lang.Runnable を使用します。

    Activity.runOnUiThread(Runnable)
    View.post(Runnable)
    View.postDelayed(Runnable, long)
    Handler.post(Runnable)
    
  2. android.os.Message を使用します。

    Handler.sendMessage(Message) / Handler.handleMessage(Message)
    

AsyncTask を使用することもできますが、私の質問は、非常に単純なコンポーネントを更新するユース ケースに重点を置いています。両方のアプローチを使用してそれがどのように行われるか見てみましょう:

  1. ランナブルの使用:

    TextViev tv = ...;
    final String data = "hello";
    Runnable r = new Runnable() {
    
        @Override
        public void run(){
            tv.setText(data);
        }
    
    };
    //Now call Activity.runOnUiThread(r) or handler.post(r), ...
    
  2. メッセージの使用:

    Message m = handler.obtainMessage(UPDATE_TEXT_VIEW, "hello");
    handler.sendMessage(m);
    
    //Now on handler implementation:
        @Override
        public void handleMessage(Message msg) {
            if(msg.what == UPDATE_TEXT_VIEW){
                String s = (String) msg.obj;
                tv.setText(data);
            } ... //other IFs?
        }
    

私見、メッセージは次の理由で行くべき道ではありません:

  • Android 以外の新しいプログラマーには理解しにくい (構築中にハンドラーがそのスレッドにフックする)。
  • メッセージがプロセス境界を超える場合、オブジェクト ペイロードは Parcellable である必要があります。
  • メッセージは再利用されます (適切にクリーンアップしないとエラーが発生しやすいですか?)
  • ハンドラーには 2 つの役割があります (メッセージを送信するだけでなく、メッセージを処理することもできます)。
  • メッセージ属性はパブリックですが、getter/setter も提供します。

一方、Runnables はよく知られているコマンド パターンに従い、プログラマーにとってより使いやすく、読みやすくなっています。

Runnables よりも Messages を使用する利点は何でしょうか? メッセージは、現代の Android プログラミングでバックグラウンドにプッシュされますか? Runnables では実行できない Messages で実行できることはありますか?

前もって感謝します。

4

4 に答える 4

22

Messageaと aの使用にほとんど違いはないと思いRunnableます。それは主に個人的な好みに要約されます。なんで?Runnableソース コードを見ると、ポストするのとまったく同じメッセージング メカニズムが使用されていることがわかります。Runnableを aに付けてMessage送信するだけです。

4.4.2 ソースコード

public final boolean post(Runnable r) {
    return  sendMessageDelayed(getPostMessage(r), 0);
}

private static Message getPostMessage(Runnable r) {
    Message m = Message.obtain();
    m.callback = r;
    return m;
}

参照: Grep コード - ハンドラー

于 2014-03-20T13:08:17.723 に答える
15

Messages再利用できるため、作成されるオブジェクトとGCが少なくなります。また、最終的にクラスと匿名型が少なくなります。

1 つの大きな利点は、 a を aMessageに送信するクラスHandlerが、その実装について何も知る必要がないことMessageです。これは、使用される場所に応じてカプセル化に役立ちます。

最後に、両者の清浄度の違いを考えてみましょう

mHandler.obtainMessage(DO_STUFF, foo).sendToTarget();

final Foo tempFoo = foo;
mHandler.post(new Runnable(){
    @Override
    public void run(){
        doStuff(tempFoo);
    }
};

必要な場所がいくつかある場合doStuff()、前者の方がはるかに読みやすく、コードの重複が少なくなります。

于 2013-11-25T23:27:58.890 に答える
4

HandlerrunOnUiThread()ドキュメントによると、インターフェイスは よりもはるかに多くの機能を提供します。

Handler には主に 2 つの用途があります。
(1) 将来のある時点で実行されるメッセージとランナブルをスケジュールするため、
(2) 自分のスレッドとは異なるスレッドで実行されるアクションをキューに入れるため。

runOnUiThread(2) のサブセットのみを実行します。つまり、「UI スレッドで実行するアクションをキューに入れる」

したがって、これらの追加機能が必要でない限り、IMOrunOnUiThreadで十分であり、推奨される方法です。

于 2012-06-26T13:27:01.563 に答える