手書きハンドラーソースフレーム

7422 ワード

手書きでテストを見てみましょう

public class HandlerTest {
    public static void main(String[] args) {
        Looper.prepare();

        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        Looper.loop();
    }
}


Activity

public class Activity {
    public void onCreate(){

    }
    public  void onResume(){

    }
    public TextView findViewById(int id){
        return new TextView();
    }
}


MainActivity

public class MainActivity extends Activity {
    private TextView mTextView;
    private Handler mHandler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            mTextView.setText((String)msg.obj);
            System.out.println(" 2:"+Thread.currentThread());
        }
    };
    @Override
    public void onCreate() {
        super.onCreate();
        System.out.println("onCreate  ");
        mTextView=findViewById(R.id.text_view);
          new Thread(){
              @Override
              public void run() {
                  try {
                      Thread.sleep(2000);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
                  System.out.println(" 1:"+Thread.currentThread());
                  Message message=new Message();
                  message.obj=" ";
                  mHandler.sendMessage(message);
              }
          }.start();
    }

    @Override
    public void onResume() {
        super.onResume();
        System.out.println("onResume  ");
    }
}


R

public class R {
    public final static class id{
        public static final int text_view = 0x0011;
    }
}

TextView

public class TextView {
    private Thread mThread;

    public TextView() {
        mThread = Thread.currentThread();
    }
    public void setText(CharSequence text){
        checkThread();
        System.out.println("UI "+text);
    }

    private void checkThread() {
        if(mThread!=Thread.currentThread()){
            throw new RuntimeException(
                    "Only the original thread that created a view hierarchy can touch its views.");
        }
    }
}

Message

public class Message {
    public Object obj;
    public Handler target;
    public long when;
    public Message next;

}

Handlerはメッセージをメッセージキューに送信し、メッセージをメッセージキュー処理に渡す

public class Handler {
    private MessageQueue mQueue;

    public Handler() {
        Looper looper = Looper.myLooper();

        if(looper == null){
            throw new RuntimeException(
                    "Can't create handler inside thread that has not called Looper.prepare()");
        }
        mQueue=looper.mQueue;
    }

    public void sendMessage(Message message) {
        sendMessageDelayed(message,0);
    }

    private boolean sendMessageDelayed(Message msg, int delayMillis) {
        if(delayMillis<0){
            delayMillis=0;
        }
        return sendMessageAtTime(msg, System.currentTimeMillis() + delayMillis);
    }

    private boolean sendMessageAtTime(Message msg, long uptimeMillis) {
        MessageQueue queue = mQueue;
        return enqueueMessage(queue, msg, uptimeMillis);
    }

    private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
        msg.target = this;
        return queue.enqueueMessage(msg, uptimeMillis);
    }

    public void handleMessage(Message msg) {

    }
}

MessageQueueメッセージの処理

public class MessageQueue {
    private Message mMessages;

    public boolean enqueueMessage(Message msg, long when) {
        synchronized (this) {
            msg.when = when;
            Message p = mMessages;
            if (p == null || when == 0 || when < p.when) {
                msg.next = p;
                mMessages = msg;
            } else {
                Message prev;
                for (; ; ) {
                    prev = p;
                    p = p.next;
                    if (p == null || when < p.when) {
                        break;
                    }
                }
                msg.next = p; // invariant: p == prev.next
                prev.next = msg;
            }
        }
        return true;
    }

    public Message next() {
        int pendingIdleHandlerCount = -1; // -1 only during first iteration
        for (; ; ) {

            synchronized (this) {
                // Try to retrieve the next message. Return if found.
                final long now = System.currentTimeMillis();
                Message prevMsg = null;
                Message msg = mMessages;
                if (msg != null && msg.target == null) {
                    // Stalled by a barrier. Find the next asynchronous message
                    // in the queue.
                    do {
                        prevMsg = msg;
                        msg = msg.next;
                    } while (msg != null);
                }
                if (msg != null) {
                    if (now < msg.when) {
                        // Next message is not ready. Set a timeout to wake up
                        // when it is ready.
                    } else {
                        if (prevMsg != null) {
                            prevMsg.next = msg.next;
                        } else {
                            mMessages = msg.next;
                        }
                        msg.next = null;
                        return msg;
                    }
                } else {
                }

                if (pendingIdleHandlerCount <= 0) {
                    continue;
                }
            }
        }
    }
}


Looperはメッセージキュー内のデータを取り出し,Handler処理にメッセージデータを送信する

public class Looper {
    // sThreadLocal.get() will return null unless you've called prepare().
    static final ThreadLocal sThreadLocal = new ThreadLocal();

    public static void prepare() {
        sThreadLocal.set(new Looper());
    }

    MessageQueue mQueue;

    public Looper() {
        mQueue = new MessageQueue();
    }

    public static void loop() {
        Looper looper = myLooper();
        for(;;){
            MessageQueue queue = looper.mQueue;

            Message message = queue.next();

            if(message == null){
                return;
            }

            message.target.handleMessage(message);
        }
    }

    static Looper myLooper() {
        return sThreadLocal.get();
    }
}

ActivityThread

public class ActivityThread {
    final H mH = new H();
    public void attach(boolean b) {
        Activity mainActivity = new MainActivity();
        mainActivity.onCreate();
        // handler Activity 
        Message message=new Message();
        message.obj = mainActivity;
        mH.sendMessage(message);
    }
    private class H extends Handler {
        @Override
        public void handleMessage(Message msg) {
            Activity mainActivity = (Activity) msg.obj;
            mainActivity.onResume();
        }
    }
}