志在指尖
用双手敲打未来

Android中的消息传递机制

为什么要运用Handler?
由于屏幕的改写频率是60Hz,大概16毫秒会改写一次,所以为了确保UI的流畅性,耗时操作需求在子线程中处理,子线程不能直接对UI进行更新操作。因而需求Handler在子线程发音讯给主线程来更新UI。
这里再深化一点,Android中的UI控件不是线程安全的,因而在多线程并发拜访UI的时分会导致UI控件处于不行预期的状态。Google不经过锁的机制来处理这个问题是由于:
引进锁会导致UI的操作变得复杂
引进锁会导致UI的运转功率降低
因而,Google的工程师***是经过单线程的模型来操作UI,开发者只需求经过Handler在不同线程之间切花就能够了。android
概述一下Android中的音讯机制?
Android中的音讯机制主要是指Handler的运转机制。Handler是进行线程切换的要害,在主线程和子线程之间切换仅仅一种比较特别的运用情景罢了。其间音讯传递机制需求了解的东西有Message、Handler、Looper、Looper里边的MessageQueue目标。
如上图所示,我们能够把整个音讯机制看作是一条流水线。其间:
MessageQueue是传送带,担任Message行列的传送与管理
Looper是流水线的发动机,不断地把音讯从音讯行列里边取出来,交给Handler来处理
Message是每一件产品
Handler便是工人。但是这么比方不太恰当,由于发送以及终究处理Message的都是Handler
为什么在子线程中创立Handler会抛异常?
Handler的作业是依赖于Looper的,而Looper(与音讯行列)又是属于某一个线程(ThreadLocal是线程内部的数据存储类,经过它能够在指定线程中存储数据,其他线程则无法获取到),其他线程不能拜访。因而Handler便是直接跟线程是绑定在一起了。因而要运用Handler必需要确保Handler所创立的线程中有Looper目标而且发动循环。由于子线程中默许是没有Looper的,所以会报错。
正确的运用办法是:
handler=null;
newThread(newRunnable(){
privateLoopermLooper;
@Override
publicvoidrun(){
//有必要调用Looper的prepare办法为当时线程创立一个Looper目标,然后发动循环
//prepare办法中本质是给ThreadLocal目标创立了一个Looper目标
//假如当时线程已经创立过Looper目标了,那么会报错
Looper.prepare();
handler=newHandler();
//获取Looper目标
mLooper=Looper.myLooper();
//发动音讯循环
Looper.loop();
//在恰当的时分退出Looper的音讯循环,避免内存泄漏
mLooper.quit();
}
}).start();
主线程中默许是创立了Looper而且发动了音讯的循环的,因而不会报错:
应用程序的入口是ActivityThread的main办法,在这个办法里边会创立Looper,而且执行Looper的loop办法来发动音讯的循环,使得应用程序一直运转。
子线程中能够经过Handler发送音讯给主线程吗?
能够。有时分出于业务需求,主线程能够向子线程发送音讯。子线程的Handler有必要按照上述办法创立,而且相关Looper。

未经允许不得转载:IT技术网站 » Android中的消息传递机制
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

志在指尖 用双手敲打未来

登录/注册IT技术大全

热门IT技术

C#基础入门   SQL server数据库   系统SEO学习教程   WordPress小技巧   WordPress插件   脚本与源码下载