转载请标明出处:
http://blog.csdn.net/hai_qing_xu_kong/article/details/76083113
本文出自:【顾林海的博客】
个人开发的微信小程序,目前功能是书籍推荐,后续会完善一些新功能,希望大家多多支持!
package com.glh.intentservice;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private TextView mInfoTextView;
private Button mDownloadButton;
private static Handler mHandler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initEvent();
}
private void initView() {
mInfoTextView = (TextView) findViewById(R.id.tv_info);
mDownloadButton = (Button) findViewById(R.id.btn_download);
}
private void initEvent() {
mDownloadButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mInfoTextView.setText("下载中...");
new DownloadThread(0).start();
}
});
}
class DownloadThread extends Thread {
private int mProcess = 0;
DownloadThread(int process) {
mProcess = process;
}
@Override
public void run() {
while (mProcess < 100) {
mProcess++;
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Runnable runnable = new Runnable() {
@Override
public void run() {
mInfoTextView.setText("下载成功");
}
};
mHandler.post(runnable);
}
}
}
package com.glh.intentservice;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.lang.ref.WeakReference;
public class MainActivity extends AppCompatActivity {
private TextView mInfoTextView;
private Button mDownloadButton;
private MyHandler mHandler = new MyHandler(this);
static class MyHandler extends Handler {
private WeakReference weakReference;
MyHandler(MainActivity activity) {
weakReference = new WeakReference<>(activity);
}
@Override
public void handleMessage(Message msg) {
MainActivity activity = weakReference.get();
if (null != activity) {
int what = msg.what;
switch (what) {
case 1:
activity.downloadSuccess((String) msg.obj);
break;
default:
break;
}
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initEvent();
}
private void initView() {
mInfoTextView = (TextView) findViewById(R.id.tv_info);
mDownloadButton = (Button) findViewById(R.id.btn_download);
}
private void initEvent() {
mDownloadButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mInfoTextView.setText("下载中...");
new DownloadThread(0).start();
}
});
}
private void downloadSuccess(String info) {
mInfoTextView.setText(info);
}
class DownloadThread extends Thread {
private int mProcess = 0;
DownloadThread(int process) {
mProcess = process;
}
@Override
public void run() {
while (mProcess < 100) {
mProcess++;
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Message message = Message.obtain();
message.what = 1;
message.obj = "下载成功";
mHandler.sendMessage(message);
}
}
}
在讲解Handler机制时,先来了解一下Looper、MessageQueue、Message所代表的含义。Handler主要包含两种作用,分别是发送消息到消息队列和处理消息;Looper用于为当前线程生成一个消息队列,并执行一个循环,不停的从消息队列中获取Message消息;MessageQueue就是一个先进先出的消息队列,提供了next方法用于获取Message消息,以及enqueueMessage方法将消息添加到消息队列中;Message代表消息。
在Android中新开启的线程是没有开启消息循环的(主线程除外),如果在子线程中开启消息循环就需要这样做:
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
}
在run方法中主要三件事:
public static void prepare() {
prepare(true);
}
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));
}
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
public static void loop() {
final Looper me = myLooper();
final MessageQueue queue = me.mQueue;
for (; ; ) {
//没有消息时阻塞
Message msg = queue.next(); // might block
if (msg == null) {
return;
}
try {
//通过Handler方法消息
msg.target.dispatchMessage(msg);
} finally {
if (traceTag != 0) {
Trace.traceEnd(traceTag);
}
}
//消息的回收
msg.recycleUnchecked();
}
}
最后看看Handler的源码:
public Handler() {
this(null, false);
}
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();
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;
}
mLooper是之前在Loop.prepare()方法执行时关联的Looper对象,这这段代码中会去判断mLooper是否空,如果为空抛出异常,说明创建Handler之前需要通过Looper.prepare()方法创建当前线程的Looper对象并创建一个MessageQueue消息队列,这样的话Handler才能与MessageQueue进行关联,这里面mQueue就是Looper创建的MessageQueue对象。
Handler创建完毕后就需要我们进行发送消息,这里主要分析前面两种Handler使用方法:
public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
一直往下追溯,最终调用的是enqueueMessage方法,在enqueueMessage方法中,将当前的Handler赋值给Message的target属性,这里面的msg.target是不是很熟悉,在之前Looper.loop()方法中进行消息队列的遍历,最终就是通过它来发送消息的。这里的queue就是与当前线程关联的Looper对象的MessageQueue,执行到最后通过MessageQueue的enqueueMessage方法将Message放入消息队列中。
接着查看sendMessage(message)方法的实现原理:
public final boolean sendMessage(Message msg)
{
return sendMessageDelayed(msg, 0);
}
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
public interface Callback {
public boolean handleMessage(Message msg);
}
如果通过post(runnable)方法处理消息,这时会执行handleCallback(msg)方法:
private static void handleCallback(Message message) {
message.callback.run();
}
到此Handler机制原理解析完毕。