Handlerの3:コンストラクション関数のソースコード解析

13899 ワード

Handlerコンストラクション関数、インスタンスの作成
概要
Handlerの構造は2つのクラスに分けられ,1つはUIスレッドでインスタンスを作成し,1つは非UIスレッドでインスタンスを作成する.違いはLooperの入手方法です.
コンストラクションメソッドを使用したインスタンスの作成
UIスレッドでのインスタンスの作成
private Handler mHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            return false;
        }
    });

UI以外のスレッドでのインスタンスの作成
class LooperThread extends Thread{
        @Override
        public void run() {
        	//1.   Looper
            Looper.prepare();
            //2.  Handler  
            new Handler(new Handler.Callback() {
                @Override
                public boolean handleMessage(Message msg) {
                    return false;
                }
            });
            //3.Looper  
            Looper.loop();
        }
    }

ソース分析
  • UIスレッド作成例j
  • public Handler() {
            this(null, false);
        }
        
    public Handler(Callback callback) {
            this(callback, false);
        }
    
    public Handler(boolean async) {
            this(null, async);
        }
    
    public Handler(Callback callback, boolean async) {
          	......
        }
    
    

    1.Callback:メソッドコールバック、MessageをUIスレッドに戻す
     public interface Callback {
            /**
             * @param msg A {@link android.os.Message Message} object
             * @return True if no further handling is desired
             */
            public boolean handleMessage(Message msg);
        }
    

    2.async:trueは非同期、falseは同期
    // async true 
     msg.setAsynchronous(true);
    

    3.以下は、上記のすべての構成方法において示された最後の全文である
    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());
                }
            }
    
    		//  Looper,  UI      Looper
            mLooper = Looper.myLooper();
            if (mLooper == null) {
                throw new RuntimeException(
                    "Can't create handler inside thread that has not called Looper.prepare()");
            }
            //     
            mQueue = mLooper.mQueue;
            //  CallBack,async  
            mCallback = callback;
            mAsynchronous = async;
        }
    
  • 非UIスレッド作成インスタンス
  • public Handler(Looper looper) {
            this(looper, null, false);
        }
    
     public Handler(Looper looper, Callback callback) {
            this(looper, callback, false);
        }
        
     public Handler(Looper looper, Callback callback, boolean async) {
     		//  looper,callback,async  
            mLooper = looper;
            mQueue = looper.mQueue;
            mCallback = callback;
            mAsynchronous = async;
        }
    

    まとめ
    1.UIスレッドはすでにLooperを初期化しているので、再初期化する必要はなく、他のスレッドは初期化していないので、初期化する必要があります.