标签:android blog http java 使用 os io 数据
package com.example.testlibrary;
import android.os.Handler;
import android.os.Looper;
public class LooperTheread extends Thread{
public Handler mhHandler;
@Override
public void run() {
// 1. 调用Looper
Looper.prepare();
// ... 其他处理,例如实例化handler
// 2. 进入消息循环
Looper.loop();
}
}
// 每个线程中的Looper对象其实是一个ThreadLocal,即线程本地存储(TLS)对象
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
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();
}通过源码,我们可以轻松了解Looper的工作方式,其核心就是将Looper对象定义为ThreadLocal。如果不理解ThreadLocal,可以参考我这篇文章:正确理解ThreadLocal /**
* Run the message queue in this thread. Be sure to call
* {@link #quit()} to end the loop.
*/
public static void loop() {
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
// 取出这个Looper的消息队列
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;
}
// 处理消息,Message对象中有一个target,它是Handler类型
msg.target.dispatchMessage(msg);
msg.recycle();
}
}
/**
* Return the Looper object associated with the current thread. Returns
* null if the calling thread is not associated with a Looper.
*/
public static Looper myLooper() {
return sThreadLocal.get();
}通过上面的分析会发现,Looper的作用是: final MessageQueue mQueue; // Handler中也有一个消息队列
final Looper mLooper; // 也有一个Looper
final Callback mCallback; // 有一个回调类这几个成员变量的使用,需要分析Handler的构造函数。Handler一共有四个构造函数,它们的区别就在于对上面成员变量的初始化上,下面我们来看一下四个构造函数的源码: // 构造函数1
public Handler() {
// 获得调用线程的Looper
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
// 得到Looper的消息队列
mQueue = mLooper.mQueue;
// 无callback设置
mCallback = null;
}
// 构造函数2
public Handler(Callback callback) {
// 获得调用线程的Looper
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()");
}
// 得到Looper的消息队列
mQueue = mLooper.mQueue;
// 和构造函数1相比,多了callback设置
mCallback = callback;
}
// 构造函数3
public Handler(Looper looper) {
// looper由外部传入,是哪个线程的Looper不确定
mLooper = looper;
mQueue = mLooper.mQueue;
mCallback = null;
}
// 构造函数4
public Handler(Looper looper, Callback callback) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
}通过上面的构造函数,我们可以发现,Handler中的MessageQueue最终都会指向关联Looper的MessageQueue。public class LooperThread extends Thread{
public Handler mhHandler;
@Override
public void run() {
// 1. 调用Looper
Looper.prepare();
// ... 其他处理,例如实例化handler
Handler handler = new Handler();
// 2. 进入消息循环
Looper.loop();
}
}加入Handler的效果图如下所示: public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain(); // 得到空的message
m.callback = r; // 将runnable设置为message的callback
return m;
}
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}最终发送消息都会调用sendMessageAtTime函数,我们看一下它的源码实现: 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; // 将Message的target设置为自己,然后加到消息队列中
if (mAsynchronous) {
msg.setAsynchronous(true);
}
return queue.enqueueMessage(msg, uptimeMillis);
}
/**
* Handle system messages here.
*/
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
private static void handleCallback(Message message) {
message.callback.run();
}
/**
* Subclasses must implement this to receive messages.
*/
public void handleMessage(Message msg) {
}dispatchMessage定义了一套消息处理的优先级机制,它们分别是: /**
* Return a new Message instance from the global pool. Allows us to
* avoid allocating new objects in many cases.
*/
public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
sPoolSize--;
return m;
}
}
return new Message();
}
/** Constructor (but the preferred way to get a Message is to call {@link #obtain() Message.obtain()}).
*/
public Message() {
} /**
* arg1 and arg2 are lower-cost alternatives to using
* {@link #setData(Bundle) setData()} if you only need to store a
* few integer values.
*/
public int arg1;
/**
* arg1 and arg2 are lower-cost alternatives to using
* {@link #setData(Bundle) setData()} if you only need to store a
* few integer values.
*/
public int arg2;
/**
* Sets a Bundle of arbitrary data values. Use arg1 and arg1 members
* as a lower cost way to send a few simple integer values, if you can.
* @see #getData()
* @see #peekData()
*/
public void setData(Bundle data) {
this.data = data;
}3. 用Message.what来标识信息,以便用不同方式处理message。public class MainActivity extends Activity {
TextView mTextView;
MyHandler mHandler = new MyHandler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView)findViewById(R.id.test1);
new Thread(new UpdateTitleTask(mHandler)).start();
}
private class MyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
Bundle bundle = msg.getData();
mTextView.setText(bundle.getString("title", ""));
}
}
}public class UpdateTitleTask implements Runnable{
private Handler handler;
public UpdateTitleTask(Handler handler) {
this.handler = handler;
}
private Message prepareMsg() {
Message msg = Message.obtain();
Bundle bundle = new Bundle();
bundle.putString("title", "From Update Task");;
msg.setData(bundle);
return msg;
}
@Override
public void run() {
try {
Thread.sleep(2000);
Message msg = prepareMsg();
handler.sendMessage(msg);
} catch (InterruptedException e) {
}
}
}Android消息处理机制(源码分析),布布扣,bubuko.com
标签:android blog http java 使用 os io 数据
原文地址:http://blog.csdn.net/wzy_1988/article/details/38346637