android学習(2)マルチスレッドの理解

3114 ワード

マルチスレッド操作UIの動作原理:
UIスレッド:まずappを起動すると、システムは自動的にUIスレッドを起動し、その後、このスレッドはLooperを作成し(注:Looperコンストラクション関数はMessageQueueのメッセージキューに変数mQueueが存在する)、loopメソッドを呼び出すことによって無限ループのforを実行し、このforにはMessageQueueがある.next()メソッドは、メッセージキュー内のMessage(メッセージキューが空の場合はブロック待ち)を絶え間なく検索し、Messageを取得するとmessageを実行する.target(このフィールドに格納されているHandlerクラスのインスタンス)のdispatchMessage(Message msg)メソッドを実行し、recycle()メソッドを実行してMessageオブジェクトを回収します(システムは50個のMessageオブジェクトプールを維持します).
 
Handler:サブスレッドの結果がUIスレッドにフィードバックされる必要がある場合、HandlerはUIスレッドで如実にインスタンス化する必要があり、逆にサブスレッドでHandlerをインスタンス化する必要があります.Handlerのデフォルトインスタンス化で使用されるLooperは、現在のスレッドのLooperです
Handler部分コード切り取り:
public Handler(Callback callback, boolean async) {

        if (FIND_POTENTIAL_LEAKS) {

            final Class<? extends Handler> klass = getClass();

            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&

                    (klass.getModifiers() & Modifier.STATIC) == 0) {

                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +

                    klass.getCanonicalName());

            }

        }



        mLooper = Looper.myLooper();//             Looper   mLooper   

        if (mLooper == null) {

            throw new RuntimeException(

                "Can't create handler inside thread that has not called Looper.prepare()");

        }

        mQueue = mLooper.mQueue;

        mCallback = callback;

        mAsynchronous = async;

}


Handlerクラスはどのくらいのコンストラクタを提供しており,そのスレッドを使用するLooperを直接指定することができる.
public Handler(Looper looper)
詳細なコンストラクタは、ソースコードを参照してください.
 
サブスレッド:サブスレッドの作成(HandlerThread:デフォルトでは独自のLooperを作成し、Thread:Looperが必要な場合は手動で作成する)、サブスレッドで実行する必要があるコードを指定し、コードの実行時に結果がUIスレッドにフィードバックされる必要がある場合(UIに値を表示するなど)、このHandler(このHandlerはUIスレッドのHandlerでなければならない、つまりUIスレッドのLooperインスタンスを使用しなければならない)のMessageをUIスレッドのMessageQueueに押し込むだけでよい.このHandlerに対応するMessageインスタンスを取得する方法:HandlerのobtainMessage()メソッドを呼び出すことができます.Message Queueに押し込む方法:HandlerのsendMessage(sendEmptyMessageDelayed、sendEmptyMessageAtTime....自分のニーズに合わせて方法を選択)またはMessageを呼び出すsendToTarget()メソッドですが、実はこのメソッドはmessageが自分のtarget変数(Handlerのインスタンスを格納)を呼び出すsendMessage(Message msg)メソッドで、それから自分をメソッドのパラメータとして渡します.
 
補足:HandlerのdispatchMessageメソッドに注目してください.
Handler部分コードは以下の通りです.
final Callback mCallback;

public interface Callback {

        public boolean handleMessage(Message msg);

} 

     /* Subclasses must implement this to receive messages.

     */

    public void handleMessage(Message msg) {

    }

    

public void dispatchMessage(Message msg) {

        if (msg.callback != null) {//  msg callback         

            handleCallback(msg);

        } else {

            if (mCallback != null) {//  Handler    Callback,              handleMessage

                if (mCallback.handleMessage(msg)) {

                    return;

                }

            }

            handleMessage(msg);//             

        }

    }


 
 
正しくないところや厳格でないところがあれば、指摘、検討を歓迎します.ありがとう!