Looper主要完成Handler与MessageQueue进行交互,主要用于线程间通信;
线程间通信:大家都知道子线程不能直接操作主线程(UI线程),也都知道ui线程已经为我们创建了looper;
//Thread1
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
System.out.println("这个消息是从-->>" + msg.obj
+ "过来的,在" + "btn的子线程当中" + "中执行的");
Toast.makeText(MainActivity.this, ":" + msg.obj, Toast.LENGTH_LONG).show();
}
};
Looper.loop();
}
}).start();
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//Thread2
new Thread(new Runnable() {
@Override
public void run() {
// Looper.prepare();
Message message = Message.obtain();
message.obj = getClipBoard();
System.out.println("这个消息是从----->>" + message.obj
+ "过来的,在" + "btn的子线程当中" + "中执行的");
// Toast.makeText(MainActivity.this, ":--" + message.obj, Toast.LENGTH_LONG).show();
handler.sendMessage(message);
// Looper.loop();
}
}).start();
}
});
Thread1中如果不加入Looper.prepare() 则会报错:不能在没有调用Looper.prepare()的子线程中创建handler;
Looper.prepare() 实际是创建looper;
Looper.loop()中实现了一个死循环不断的从messageQueue中取出Message,转交给message.target即Handler进行处理:
Looper 源码:
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}
public static void loop() {
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
final MessageQueue queue = me.mQueue;
...
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
...
try {
msg.target.dispatchMessage(msg);
dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
...
msg.recycleUnchecked();
}
}
Looper:成员变量 :mQueue =new MessageQueue,mThread 中通过ThreadLocal((线程局部变量)将私有线程和该线程存放的副本对象作为一个映射,各个线程间变量互不干扰)为了确保每个线程只对应一个Looper
Handler成员变量:mLooper=Looper.myLooper()、mQueue = mLooper.mQueue、mCallback
通过mLooper and mQueue将looper与Handler关联起来
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
690 MessageQueue queue = mQueue;
691 if (queue == null) {
692 RuntimeException e = new RuntimeException(
693 this + " sendMessageAtTime() called with no mQueue");
694 Log.w("Looper", e.getMessage(), e);
695 return false;
696 }
697 return enqueueMessage(queue, msg, uptimeMillis);
698 }
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
741 msg.target = this;//****
742 if (mAsynchronous) {
743 msg.setAsynchronous(true);
744 }
745 return queue.enqueueMessage(msg, uptimeMillis);
746 }