android中的handler机制,Android中的Handler机制

还记得第一次使用Handler的情形,我开启了一个子线程,在子线程中给TextView进行setText(),然后运行起来程序异常终止了,查看log信息:Handler的作用?1)在非UI

还记得第一次使用Handler的情形,我开启了一个子线程,在子线程中给TextView进行setText(),然后运行起来程序异常终止了,查看log信息:

E/AndroidRuntime(2206): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

goolgle一下找到了原因: 原来android中相关的view和控件不是线程安全的,我们必须单独做处理。然后就了解了Handler。可以在子线程中通过Handler发送一个Message给主线程,然后在主线程进行UI更新

1fac44b648f5c0bf956ab10544101a0e.png

可以大概看成Handler的作用有分发消息,处理消息,发送消息,移除消息

下面看一下Message类

f76cff605599719c2ecb5fbd9b83609a.png

可见Message包括what(message的标识) 、obj 任意对象, arg1 arg2, 而且可以设置Target来指定Handler

当Handler发送一条Message时有一下两种写法:

Message msg = Message.obtain();

msg.what = 200;

msg.obj = obj;

handler.sendMessage(msg);

Message.obtain(handler, 200).sendToTarget();

Looper类:

dcc327b047313761acd881356cec3a8d.png

Looper的类注释中

Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, call prepare in the thread that is to run the loop, and then loop to have it process messages until the loop is stopped.

Most interaction with a message loop is through the Handler class.

This is a typical example of the implementation of a Looper thread, using the separation of prepare and loop to create an initial Handler to communicate with the Looper.

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

}

}

Handler的作用?

1)在非UI线程更新UI ;

2)发送一个延时消息;

3)当做定时器,每隔一段时间发送一次消息,如进行图片轮播

为什么android设计只能UI线程更新UI?

1) 解决多线程并发的问题

2) 提高界面更新的性能问题

3) 架构设计的简单

Handler 相关的异常

1)E/AndroidRuntime(2206): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

不能子线程更新UI的异常{解决:在子线程向主线程中的handler发送Message}

2E/AndroidRuntime(2329): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

不能在子线程中new Handlder(),我们需要调用Looper.prepare(); 后new Handler然后 Looper.loop();

我们自己创建的线程中没有Looper对象,这里注意一点,在ActivityThread线I程中会隐士的调用Looper.prepare()方法

在下面我们会看一下Looper.prepare()方法的源码

Handler、Looper、MessageQueue之间的关系(源码角度分析)?

Handler 的构造方法:

/**

* Use the {@link Looper} for the current thread with the specified callback interface

* and set whether the handler should be asynchronous.

*

* Handlers are synchronous by default unless this constructor is used to make

* one that is strictly asynchronous.

*

* Asynchronous messages represent interrupts or events that do not require global ordering

* with represent to synchronous messages. Asynchronous messages are not subject to

* the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.

*

* @param callback The callback interface in which to handle messages, or null.

* @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for

* each {@link Message} that is sent to it or {@link Runnable} that is posted to it.

*

* @hide

*/

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

}

}

//获取Looper

mLooper = Looper.myLooper();

if (mLooper == null) {

throw new RuntimeException(

"Can't create handler inside thread that has not called Looper.prepare()");

}

mQueue = mLooper.mQueue; //获取Looper中的MessageQueue

mCallback = callback;

mAsynchronous = async;

}

Looper.myLooper();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值