重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
大家都知道Handler是Android为了能在子线程更新UI所创作出来的一个类.
成都创新互联一直秉承“诚信做人,踏实做事”的原则,不欺瞒客户,是我们最起码的底线! 以服务为基础,以质量求生存,以技术求发展,成交一个客户多一个朋友!为您提供网站设计、做网站、成都网页设计、小程序制作、成都网站开发、成都网站制作、成都软件开发、app软件定制开发是成都本地专业的网站建设和网站设计公司,等你一起来见证!那么为什么Handler能在handler里面能更新UI。是因为Handler 把更新UI的操作切换到了主线程来操作.
有些博客说Handler是线程之间的一种通讯方式,这只局限于子线程跟主线程之间,
那么子线程是怎么把消息传送到主线程来操作,这其中一个关键的地方就是Looper.
从例子我们可以知道 假如现在有一段主要的代码
oncrete(){
new Thread(new Runnable(){
run{
//进行UI操作 ---这样是会报错的 那么我们加上handler
// 之前是没有的,现在加上Looper
Looper.prepare();
new Handler(){
handlerMessage(){
//进行UI操作 ---
// 如果是这样依然会报错 因为子线程中现在还没有Looper,会报没有Looper那个错误信息(从源码可以看到加了Looper检测) 那么我们加上Looper
}
}
Looper.loop();
}
}).start;
}
从上面的代码中 加了Looper之后还是会报错,报应该在主线程中执行UI操作.
那么是为什么,原因在于 这个Looper不是主线程的Looper
一个解决方法是 把Looper.prepare();改成Looper.getMainLooper();
或者 new Handler(Looper.getMainLooper);
这样就可以更新UI不会报错了,
那么Looper是怎样把更新UI的操作切换到主线程
我们从源码可以看到 当我们new Handler(Looper.getMainLooper())的时候 里面有
Handler(Looper looperCallback callbackasync) { = looper= looper.mQueue= callback= async}
所以说这个时候 handler已经拿到了主线程的Looper;
然后我们在Looper的loop();方法里面看到
{ msg.target.dispatchMessage(msg)} { (traceTag != ) { Trace.(traceTag)} }
会调用msg.target 这个msg.target是在这里拿到
Looper me = ()(me == ) { RuntimeException()} MessageQueue queue = me.mQueue
() { Message msg = queue.next()(msg == ) { }
在loop()方法里面Looper会开始无限循环 去处理信息啦。
顺序是以下这样
1:实例化Activity 的时候创建ActivityThread(主线程) 然后在Main()里面创建Looper 然后Looper里面通过mThreadLocal 的set方法保存主线程
然后再调用Looper.loop();这时候会开启无限循环
2:Looper.getMainLooper 会调用get方法 这个时候就拿到了主线程的Looper 以及里面保存的messageQueue
然后 handler调用post 其实也就是在主线程的messageQueue上插入一个信息
那么loop 方法里面就检测到了,这时候已经是切换到主进程了.
看源码比较能清晰整个流程
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。