Android -- Looper.prepare()とLooper.loop()

13503 ワード

AndroidのLooperクラスは、androidスレッドでメッセージ処理を行うメッセージループとメッセージキューをカプセル化するためのクラスです.handlerは、メッセージキューにメッセージを挿入するためのツールクラスと見なすことができます.(1)Looperクラスは、スレッドに対してメッセージループを開くために使用される.デフォルトではandroidで新しく誕生したスレッドはメッセージループを開いていません.(メインスレッドを除くと、メインスレッドシステムは自動的にLooperオブジェクトを作成し、メッセージループを開きます.)LooperオブジェクトはMessageQueueによってメッセージとイベントを格納します.1つのスレッドには1つのLooperしかありません.MessageQueueに対応します.(2)通常はHandlerオブジェクトによってLooperと対話する.Handlerは、指定されたLooperにメッセージを送信し、処理方法を定義するためのLooperのインタフェースと見なすことができる.デフォルトでは、Handlerは、定義されたスレッドのLooperにバインドされます.たとえば、Handlerはプライマリ・スレッドで定義され、プライマリ・スレッドのLooperにバインドされます.mainHandler=new Handler()はnew Handler(Looper.myLooper()に等しい.Looper.myLooper():現在のプロセスのlooperオブジェクト、類似のLooperを取得します.getMainLooper()は、プライマリスレッドのLooperオブジェクトを取得するために使用されます.(3)非プライマリスレッドで直接new Handler()は、E/Android Runtime(6173):Uncaaught handler:thread Thread-8 exiting due to uncaught exception E/Android Runtime(6173):java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()主スレッド以外でLooperオブジェクトがデフォルトで作成されていないため、Looperを呼び出す必要がある.prepare()Looperを有効にします.(4) Looper.loop(); Looperに作業を開始させ,メッセージキューからメッセージを取り出し,メッセージを処理する.注意:Looperに書きます.loop()以降のコードは実行されません.この関数の内部にはmHandlerが呼び出されるループがあるはずです.getLooper().quit()後、loopは中止され、その後のコードが実行されます.(5)以上の知識に基づいて,プライマリスレッドがサブスレッド(非プライマリスレッド)にメッセージを送信することを実現する.次の例のmHandlerをクラスメンバーとして宣言し,メインスレッドでmHandlerを介してメッセージを送信すればよい.Android公式ドキュメントのLooperの紹介:Class used to run a message loop for a thread.Threads by default do not have a message loop associated with them; to create one, call prepare() in the thread that is to run the loop, and then loop() to have it process messages until the loop is stopped.Most interaction with a message loop is through the Handler class. This is a typical example of the implementation of a Looper thread, using the separation of prepare() and loop() to create an initial Handler to communicate with the Looper.
Javaコード
class LooperThread extends Thread
{
public Handler mHandler;
public void run()
{
Looper.prepare();
mHandler = new Handler()
{
public void handleMessage(Message msg)
{
// process incoming messages here
}
};
Looper.loop();
}

スレッドでLooperを使用する場合prepare()とLooper.loop()メッセージキューを作成すると、メッセージ処理をスレッドで完了させることができます.
from: http://blog.csdn.net/dajian790626/article/details/7859960
Android HandlerThread使用例
以前にhandlerとlooperメッセージキューを検討したことがあるが,androidのhandlerは別にスレッドを開いて実行するのではなく,メインUIスレッドでは,スレッドを別途起動するにはHandlerThreadを用いて実現する必要がある.HandlerThreadを使用する場合、CallBackインタフェースを実装してhandlerMessageメソッドを書き換え、handlerMessageメソッドで自分の論理を処理する必要があります.以下に、小さな例のプログラムを示します.
Layoutファイルは簡単ですHanlderTreadスレッドを起動するためのボタンです
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    android:orientation="vertical" >



    <TextView

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:text="@string/hello" />



    <Button

        android:id="@+id/handlerThreadBtn"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="startHandlerThread" />



</LinearLayout>

Activityコードは次のとおりです.
package com.tayue;



import android.app.Activity;

import android.os.Bundle;

import android.os.Handler;

import android.os.Handler.Callback;

import android.os.HandlerThread;

import android.os.Message;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

/**

 * 

 * @author xionglei

 *

 */

public class TestHandlerActivity extends Activity implements OnClickListener{

    

    public Button handlerThreadBTN; 

    MyHandlerThread handlerThread;

    Handler handler;

    

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        //  UI     

        System.out.println("onCreate  CurrentThread = " + Thread.currentThread().getName());

        

        setContentView(R.layout.main);

        

        handlerThreadBTN = (Button) findViewById(R.id.handlerThreadBtn);

        handlerThreadBTN.setOnClickListener(this);

        

        handlerThread = new MyHandlerThread("myHanler");

        handlerThread.start();

        //  :       handler      ,     callback   ,      HandlerThread handlerMessage    Handler   handlerThread

        handler = new Handler(handlerThread.getLooper(), handlerThread);

        

        

    }



    @Override

    public void onClick(View v) {

        //          

        handler.sendEmptyMessage(1);

    }

    

    

    private class MyHandlerThread extends HandlerThread implements Callback {



        public MyHandlerThread(String name) {

            super(name);

        }



        @Override

        public boolean handleMessage(Message msg) {

            //       

            System.out.println(" handleMessage CurrentThread = " + Thread.currentThread().getName());

            return true;

        }

        

        

    }

    

    

    

    

}

ボタンをクリックして、印刷したログは以下の通りです(ここで3回クリックしました)07-06 09:32:48.776:I/system.out(780): onCreate  CurrentThread = main 07-06 09:32:55.076: I/System.out(780):  handleMessage CurrentThread = myHanler 07-06 09:32:58.669: I/System.out(780):  handleMessage CurrentThread = myHanler 07-06 09:33:03.476: I/System.out(780):  handleMessage CurrentThread = myHanler
HandlerThreadは簡単です.
もちろんandroid自身にも非同期スレッドのhandler,すなわちAsyncTaskがあり,このクラスはHandlerThreadとhandlerをカプセル化して非同期マルチスレッドの動作を実現している.
次のように使用できます.
private boolean iscancel = false; //            



    handlerThread = new HandlerThread("myHandlerThread");

                    handlerThread.start();

                    handler = new MyHandler(handlerThread.getLooper());

                //                  

                        handler.post(new Runnable() {

                            @Override

                            public void run() {

                                Message message = handler.obtainMessage();

                                UserBean user = Bbs.getInstance().Login(username, password);//    

                                Bundle b = new Bundle();

                                b.putSerializable("user", user);

                                message.setData(b);

                                message.sendToTarget(); //    handler.sendMessage(message);

                            }

                        });

    class MyHandler extends Handler {



            public MyHandler(Looper looper) {

                super(looper);

            }



            @Override

            public void handleMessage(Message msg) {

                if(iscancel == false){

                    //   UI     

                    Bundle b = msg.getData();

                    UserBean user = (UserBean)b.get("user");

                                     ......

               }

           }

    }  

from: http://blog.csdn.net/bearray123/article/details/7722990