9

私は非常に基本的なハンドラーチュートリアルでこのコードに出くわしました。progressDialog.dismiss()コードは正常に機能していますが、なぜハンドラーを使用する必要があるのか​​わかりません。 ハンドラー部分を削除 progressDialog.dismiss()してrun()メソッドに配置しましたが、正常に機能しました。では、なぜハンドラーを使用したのですか?

 import android.app.Activity;
    import android.app.ProgressDialog;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.Toast;


    public class HandlerThread extends Activity{

    private Button start;
    private ProgressDialog progressDialog;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        start = (Button) findViewById(R.id.Button01);
        start.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                fetchData();
            }

        });
    }



    protected void fetchData() {
        // TODO Auto-generated method stub
        progressDialog = ProgressDialog.show(this, "", "Doing...");
        new Thread() {
            public void run() {
                try {

                    Thread.sleep(8000);

                    } catch (InterruptedException e) {

                    }
                      messageHandler.sendEmptyMessage(0);

                    }
        }.start();


    }



    private Handler messageHandler = new Handler() {

        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            progressDialog.dismiss();

        }
    };
}
4

4 に答える 4

19

のドキュメントからView:

ビューでメソッドを呼び出すときは、常に UI スレッド上にいる必要があります。他のスレッドで作業を行っていて、そのスレッドからビューの状態を更新したい場合は、Handler.

あなたの例では、上記のドキュメントに従って、でdismiss()メソッドを呼び出すProgressDialog必要がある場合は、UI スレッドから呼び出す必要があります。クラスが (おそらく UI スレッドで)インスタンス化されると、はのmessageHandlerインスタンスに初期化されます。HandlerHandlerThread

のドキュメントからHandler:

Handlerインスタンスは、1 つのスレッドとそのスレッドのメッセージ キューに関連付けられています。新しい を作成するとHandler、それを作成しているスレッドのスレッド/メッセージ キューにバインドされます。その時点から、メッセージと実行可能ファイルがそのメッセージ キューに配信され、メッセージ キューから出てくると実行されます。 .

したがって、新しいスレッドから UI スレッドと通信するには、UI スレッドでHandler作成された にメッセージを投稿するだけです。

ViewUI スレッドの外部から でメソッドを呼び出すと、未定義の動作が呼び出されます。つまり、正常に動作しているように見える場合があります。しかし、常にうまくいくとは限りません。

于 2012-09-07T06:43:19.253 に答える
2

アプリケーションが起動すると、Androidシステムは、UIレンダリングとイベントの処理を担当するメインスレッドを持つプロセスを起動します。Android UIはスレッドセーフではないため、イベントスレッドによってのみAndroidUIにアクセスできます。プログラムで、次のコードブロックを使用して、イベント以外のスレッドを定義しました。

 new Thread() {
        public void run() {
            try {

                Thread.sleep(8000);

                } catch (InterruptedException e) {

                }
                  messageHandler.sendEmptyMessage(0);

                }
    }.start();

進行状況ダイアログを閉じたい場合は、イベントスレッドでのみ実行できます。ハンドラーは、メッセージキューのメッセージを処理/処理するために使用されます。ハンドラーはスレッドに関連付けられます。この場合は、イベントスレッドに関連付けられます。デフォルトでは、ハンドラーは、スレッドが作成されているスレッドに関連付けられます。messageHandler.sendEmptyMessage()によって、別のスレッドがハンドラーにメッセージを送信し、handlerMessageメソッドでこのメッセージを処理します。

于 2012-09-07T06:45:19.543 に答える