android handler

如果你和我一样对android的机制不很了解我建议:


(1)可以先看:http://code.google.com/p/androidlearn/wiki/handler


(2)再看:http://blog.csdn.net/gaojie314/archive/2010/11/28/6040680.aspx


(3)还有一个详细分析注释很多:http://blog.csdn.net/Innost/archive/2010/12/05/6055793.aspx


************************************************************************

handler使用Message

1.定义一个Handler

2.重写消息处理函数

3.发送消息

//创建简单的View
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.view.View;

public class BounceView extends View {
float x = 40;

public BounceView(Context context) {
super(context);
}

@Override
protected void onDraw(Canvas canvas) {
x+=10;
Paint mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(Color.GREEN);
canvas.drawCircle(x, 40, 40, mPaint);
}
}

//创建Activity
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.Window;

public class TestHandler extends Activity {
protected static final int GUIUPDATEIDENTIFIER = 0x101;

Thread myRefreshThread = null;
BounceView myBounceView = null;
//1.定义一个Handler(一般更新View)
Handler myHandler = new Handler() {
//2.重写消息处理函数
public void handleMessage(Message msg) {
switch (msg.what) {
//判断发送的消息
case TestHandler.GUIUPDATEIDENTIFIER:
//更新View
myBounceView.invalidate();
break;
}
super.handleMessage(msg);
}
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);

this.myBounceView = new BounceView(this);
this.setContentView(this.myBounceView);
new Thread(new myThread()).start();
}

class myThread implements Runnable {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
//3.发送消息
Message message = new Message();
//发送消息与处理函数里一致
message.what = TestHandler.GUIUPDATEIDENTIFIER;
//内部类调用外部类的变量
TestHandler.this.myHandler.sendMessage(message);

try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
}

利用handler.post()更新UI

1.创建一个Handler 2.调用Handler.post(Runnable r)方法 3.Runnable运行在UI所在线程,所以可以直接调用View.invalidate()

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;

public class TestHandler extends Activity {
private MyView myView;
private Handler mHandler;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myView = new MyView(this);
//创建一个Handler
mHandler = new Handler();
//调用Handler.post(Runnable r)方法
mHandler.post(new Runnable(){
@Override
public void run() {
//直接调用View.invalidate(),更新组件
myView.invalidate();
//延迟5毫秒后执行线程
mHandler.postDelayed(this, 5);
}
});
setContentView(myView);
}

class MyView extends View{
private float x = 0f;
public MyView(Context context) {
super(context);

}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
x+=1;
Paint mPaint = new Paint();
mPaint.setColor(Color.BLUE);
canvas.drawRect(x, 40, x+40, 80, mPaint);
}

}
}

在线程里直接更新UI

//在新线程里更新UI,可以直接使用postInvalidate()

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);

myView = new MyView(this);
this.setContentView(this.myView);
new Thread(new myThread()).start();
}

class myThread implements Runnable {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
//更新UI
myView.postInvalidate();
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}


*************************************************************************


在网上有许多资料对这三者关系的分析,但都比较笼统不够细致入微.

以下是自己深入源码分析其结果.



Handler 源码:

public class Handler {

private static final boolean FIND_POTENTIAL_LEAKS = false;

private static final String TAG = "Handler";



public interface Callback {

public boolean handleMessage(Message msg);

}

final MessageQueue mQueue;

final Looper mLooper;

final Callback mCallback;

IMessenger mMessenger;

/**

* Subclasses must implement this to receive messages.

*/

public void handleMessage(Message msg) {

}

public Handler() {

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 = null;

}



/**

* 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);

}

}

public Handler() {

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 = null;

}

public boolean sendMessageAtTime(Message msg, long uptimeMillis)

{

boolean sent = false;

MessageQueue queue = mQueue;

if (queue != null) {

msg.target = this;

sent = queue.enqueueMessage(msg, uptimeMillis);

}

else {

RuntimeException e = new RuntimeException(

this + " sendMessageAtTime() called with no mQueue");

Log.w("Looper", e.getMessage(), e);

}

return sent;

}




从源码分析可以看出:

handler在无参数的构造方法中对Looper就进行初始化,

并且从中得到looper的MessageQueue .

可以看出Handler就是Looper和MessageQueue的管理者和调度者.



其中最重要的是:sendMessageAtTime(Message msg, long uptimeMillis)这个方法

当你往Handler中发送Message消息的时候,从代码看出他自己并不去处理

Message ,而是交给了MessageQueue.由以下从这段代码来处理:

queue.enqueueMessage(msg, uptimeMillis), 其具体实现要看下面的对

MessageQueue的分析





Looper结构关联的内容:

Looper 源码:

public class Looper {

private static final boolean DEBUG = false;

private static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;



// sThreadLocal.get() will return null unless you've called prepare().

private static final ThreadLocal sThreadLocal = new ThreadLocal();



final MessageQueue mQueue;

volatile boolean mRun;

Thread mThread;

private Printer mLogging = null;

private static Looper mMainLooper = null;



public static final void prepare() {

if (sThreadLocal.get() != null) {

throw new RuntimeException("Only one Looper may be created per thread");

}

sThreadLocal.set(new Looper());

}

public static final void loop() {

Looper me = myLooper();

MessageQueue queue = me.mQueue;

while (true) {

Message msg = queue.next(); // might block

if (msg != null) {

if (msg.target == null) {

return;

}

if (me.mLogging!= null) me.mLogging.println(

">>>>> Dispatching to " + msg.target + " "

+ msg.callback + ": " + msg.what

);

msg.target.dispatchMessage(msg);

if (me.mLogging!= null) me.mLogging.println(

"<<<<< Finished to " + msg.target + " "

+ msg.callback);

msg.recycle();

}

}

}


从源码可以看出Looper 封装的信息:



Looper实质上是对当前线程, ThreadLocal,MessageQueue的封装,也就是负责在多线程

之间传递消息的一个循环器.



当你往Handler中添加消息的时候则,里面这个方法: public static final void loop()死循环的方法就会被系统调用,之后的功能代码是:

msg.target.dispatchMessage(msg),则从MessageQueue中得到一个

Message(msg),之后调用Handler的dispatchMessage(msg),这个方法内部实际调用的就是 Handler.handleMessage(msg)方法,这个就是我们在

activity要重写的方法,所以我们就能够得到其他子线程传递的Message了.



Message的源码分析:

public final class Message implements Parcelable {

public int what;

public int arg1;

public int arg2;

public Object obj;

public Messenger replyTo;

long when;

Bundle data;

Handler target;

Runnable callback;

Message next;

private static Object mPoolSync = new Object();

private static Message mPool;

private static int mPoolSize = 0;

private static final int MAX_POOL_SIZE = 10;




When: 向Handler发送Message生成的时间

Data: 在Bundler 对象上绑定要线程中传递的数据

Next: 当前Message 对一下个Message 的引用

Handler: 处理当前Message 的Handler对象.

mPool: 通过字面理解可能叫他Message池,但是通过分析应该叫有下一个Message引用的Message链更加适合.

其中Message.obtain(),通过源码分析就是获取断掉Message链关系的第一个Message.

MessageQueue



public class MessageQueue {

Message mMessages;

private final ArrayList mIdleHandlers = new ArrayList();

private boolean mQuiting = false;

boolean mQuitAllowed = true;



public static interface IdleHandler {

boolean queueIdle();

}



public final void addIdleHandler(IdleHandler handler) {

if (handler == null) {

throw new NullPointerException("Can't add a null IdleHandler");

}

synchronized (this) {

mIdleHandlers.add(handler);

}

}



final boolean enqueueMessage(Message msg, long when) {

if (msg.when != 0) {

throw new AndroidRuntimeException(msg

+ " This message is already in use.");

}

if (msg.target == null && !mQuitAllowed) {

throw new RuntimeException("Main thread not allowed to quit");

}

synchronized (this) {

if (mQuiting) {

RuntimeException e = new RuntimeException(

msg.target + " sending message to a Handler on a dead thread");

Log.w("MessageQueue", e.getMessage(), e);

return false;

} else if (msg.target == null) {

mQuiting = true;

}



msg.when = when;

//Log.d("MessageQueue", "Enqueing: " + msg);

Message p = mMessages;

if (p == null || when == 0 || when < p.when) {

msg.next = p;

mMessages = msg;

this.notify();

} else {

Message prev = null;

while (p != null && p.when <= when) {

prev = p;

p = p.next;

}

msg.next = prev.next;

prev.next = msg;

this.notify();

}

}

return true;

}


mMessages: 为当前序列的第一个Message, 通过源码分析 MessageQueue并不是对许多Message 之间的关系维护,这样也许可以省去很多事把,而Message 之间的关系

则统统丢给了Message自己去维护,这个可以从对Message源码分析可以理解.



mIdleHandler: 保存的是一系列的handler的集合.



其中final boolean enqueueMessage(Message msg, long when),

这个方法就是上面提到Handler 处理消息时调用到的方法,对她理解了就显

的很重要了,功能代码如下:

msg.when = when;

Message p = mMessages;
if (p == null || when == 0 || when < p.when) {

msg.next = p;

mMessages = msg;

this.notify();

} else {

Message prev = null;

while (p != null && p.when <= when) {

prev = p;

p = p.next;

}

msg.next = prev.next;

prev.next = msg;

this.notify();

}




当向MessageQueue中添加消息的时候,判断当前的Message(mMessage)是否为空,

如果为空: 则把要添加的Message(msg)赋给当前的Message(mMessage),并且将msg.next属性设为空,

如果不为空: 则循环把当前的Message(mMessage)的下一个Message(next)进行遍历,用prev记住当前的message,直到找到prev的下一个Message为空的时候就退出循

环,最后将msg接到prev的屁股后面,即这段代码: prev.next = msg;


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/gaojie314/archive/2010/11/28/6040680.aspx
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值