手書きハンドラーソースフレーム
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();
}
}
}