web-dev-qa-db-ja.com

runOnUiThreadが同じことをしている間にハンドラーを使用する理由は何ですか?

HandlersrunOnUiThread の両方の概念に出会いました。しかし、私にとっては、どの事実に基づいてそれらが正確に異なるのか、まだ疑問のようです。

どちらも、バックグラウンドスレッドからUIアクションを実行することを目的としています。しかし、2つの方法から選択する際に考慮すべき要因は何ですか。

たとえば、バックグラウンドでWebサービスを実行するRunnableThreadを考えてみましょう。ここでUIを更新します。

UIを更新する最良の方法は何ですか? HandlerまたはrunOnUiThreadに行くべきですか?

AsyncTaskを使用してonPostExecuteを使用できることはまだわかっています。しかし、違いを知りたいだけです。

51
Andro Selva

Activity.runOnUiThread() は、より一般的な特殊なケースです HandlersHandlerを使用すると、独自のスレッド内で独自のイベントクエリを作成できます。 デフォルトコンストラクターでインスタンス化されたHandlersを使用すると、does n'tは "code一般的にUIスレッドで実行されます」。デフォルトでは、ハンドラーはインスタンス化元のThreadにバインドされます。

UI(メイン)スレッドへのバインドが保証されるHandlerを作成するには、Main LooperにバインドされたHandlerオブジェクトを作成する必要がありますこの:

_Handler mHandler = new Handler(Looper.getMainLooper());
_

さらに、runOnUiThread()メソッドの実装を確認する場合、Handlerを使用して次のことを行います。

_  public final void runOnUiThread(Runnable action) {
        if (Thread.currentThread() != mUiThread) {
            mHandler.post(action);
        } else {
            action.run();
        }
    }
_

上記のコードスニペットからわかるように、runOnUiThread()がUIスレッドから呼び出されると、_Runnable action_がすぐに実行されます。それ以外の場合は、Handlerにポストします。これは、後のある時点で実行されます。

75
HitOdessit

ハンドラーには、メッセージパッシングなどの多くの作業があり、タスクを実行するためにスレッドを開始すると頻繁にUIが更新されます。スレッドのMessageQueueに関連付けられた実行可能なオブジェクト。これは、Bluetoothチャット、Wi-Fiチャットなどの多くのアプリケーションで非常に便利です。

あなたはこれを見なければなりません

http://developer.Android.com/guide/components/processes-and-threads.html

http://developer.Android.com/tools/testing/activity_testing.html

1
Vipin Sahu

HitOdessitの回答に続きます。

このようなクラスを作成できます。

public class Global{
    private static Handler mHandler = new Handler(Looper.getMainLooper());
    public static void runOnUiThread(Runnable action){
        mHandler.post(action);
    }
}

そして、このように呼び出します。

Global.runOnUiThread(new Runnable(){
    //Your code
});

そして、これはどこからでも実行できます(グローバルクラスにアクセスできる場所)。

1
user7366285

ハンドラーは古い方法(APIレベル1)で、AsycTask(APIレベル1)の使用に重点を置いて、runOnUIThread(APIレベル3)が導入されました。ハンドラーの使用はできるだけ避け、必要に応じて他の2つを選択する必要があります。

0
Animesh

UIを更新する最良の方法は何ですか? HandlerまたはrunOnUiThreadに行くべきですか?

RunnableでUIを更新する必要がある場合は、runOnUiThreadに投稿してください。

ただし、UIスレッドにRunnableを常に投稿できるとは限りません。

ネットワーク/ IO操作またはWebサービスを呼び出す必要があるシナリオを考えてください。この場合、RunnableをUIスレッドに投稿できません。 Android.os.NetworkOnMainThreadExceptionをスローします

これらのタイプのRunnableは、 HandlerThread のような異なるスレッドで実行する必要があります。操作の完了後、UIスレッドに関連付けられているHandlerを使用して、結果をUIスレッドにポストバックできます。

public void onClick(View view) {

    // onClick on some UI control, perform Network or IO operation

    /* Create HandlerThread to run Network or IO operations */
    HandlerThread handlerThread = new HandlerThread("NetworkOperation");
    handlerThread.start();

    /* Create a Handler for HandlerThread to post Runnable object */
    Handler requestHandler = new Handler(handlerThread.getLooper());

   /* Create one Handler on UI Thread to process message posted by different thread */

    final Handler responseHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            //txtView.setText((String) msg.obj);
            Toast.makeText(MainActivity.this,
                    "Runnable on HandlerThread is completed and got result:"+(String)msg.obj,
                    Toast.LENGTH_LONG)
                    .show();
        }
    };

    NetworkRunnable r1 = new NetworkRunnable("http://www.google.com/",responseHandler);
    NetworkRunnable r2 = new NetworkRunnable("http://in.rediff.com/",responseHandler);
    requestHandler.post(r1);
    requestHandler.post(r2);

}

class NetworkRunnable implements Runnable{
    String url;
    Handler uiHandler;

    public NetworkRunnable(String url,Handler uiHandler){
        this.url = url;
        this.uiHandler=uiHandler;
    }
    public void run(){
        try {
            Log.d("Runnable", "Before IO call");
            URL page = new URL(url);
            StringBuffer text = new StringBuffer();
            HttpURLConnection conn = (HttpURLConnection) page.openConnection();
            conn.connect();
            InputStreamReader in = new InputStreamReader((InputStream) conn.getContent());
            BufferedReader buff = new BufferedReader(in);
            String line;
            while ((line = buff.readLine()) != null) {
                text.append(line + "\n");
            }
            Log.d("Runnable", "After IO call:"+ text.toString());

            Message msg = new Message();

            msg.obj = text.toString();

            /* Send result back to UI Thread Handler */
            uiHandler.sendMessage(msg);


        } catch (Exception err) {
            err.printStackTrace();
        }
    }
}
0
Ravindra babu