Android 的消息机制(Handler消息传递机制)

出于性能优化考虑,android的UI操作并不是线程安全的,这意味着意味着如果有多个线程并发操作UI组件,可能导致线程安全问题,未解决此问题,

从开发的角度来说, Handler 是 Android 消息机制的上层接口, 这使得在开发过程中只需要和 Handler 交互即可。 Handler 的使用过程很简单,通过它可以轻松地将一个任务切换到 Handler 所在的线程中去执行。很多人认为 Handler的作用是更新 UI, 这的确没错,但是更新 UI 仅仅是 Handler 的一个特殊的使用场景.具体来说是这样的: 有时候需要在子线程中进行耗时的 I/O 操作,可能是读取文件或者访问网络等,, 当耗时操作完成以后可能需要在 UI 上做一些改变, 由于 Android 开发规范的限制,我们并不能在子线程中访问 UI 控件,否则就会触发程序异常, 这个时候通过Handler 就可 以将更新 UI 的操作切换到主线程中执行。 因此,本质上来说, Handler 并是专门用于更新 UI 的,它只是常被开发者用来更新 UI。

Android 的消息机制主要是指 Handler 的运行机制, Handler 的运行需要底层的MessageQueue 和 Looper 的支撑。 MessageQueue 的中文翻译是消息队列,顾名思义, 它的内部存储了一组消息,以队列的形式对外提供插入和删除的工作。 虽然叫消息队列,但是它的内部存储结构并不是真正的队列, 而是采用单链表的数据结构来存储消息列表。 Looper的中文翻译为循环, 在这里可以理解为消息循环。由于 MessageQueue 只是一个消息的存储单元,它不能去处理消息,而 Looper 就填补了这个功能, Looper 会以无限循环的形式去查找是否有新消息,如果有的话就处理消息,否则就一直等待着。 Looper 中还有一个特殊的概念,那就是 ThreadLocal, ThreadLocal 并不是线程,它的作用是可以在每个线程中存储数据。我们知道, Handler 创建的时候会采用当前线程的 Looper 来构造消息循环系统,那么 Handler 内部如何获取到当前线程的 Looper 呢? 这就要使用 ThreadLocal 了,ThreadLocal可以在不同的线程中互不干扰地存储并提供数据,通过 ThreadLocal 可以轻松获取每个线程的 Looper。当然需要注意的是,线程是默认没有 Looper 的,如果需要使用 Handler 就必须为线程创建 Looper。我们经常提到的主线程,也叫 UI 线程,它就是ActivityThread,ActivityThread被创建时就会初始化 Looper,这也是在主线程中默认可以使用 Handler 的原因。 上面这段话是任玉刚老师书中对于android消息传递机制的描述我觉得描述的非常清晰。

android定下规则:只允许UI线程(主线程)修改Activity里的UI组件

但是应用中有时需要操作UI如获取短信验证码,有个倒计时,为此需要借助Handler消息传递机制

Handler类简介

【1】作用: 1在新启动的线程中发送消息 2在主线程中获取处理消息 主要方法 方法签名 public void handleMessage (Message msg)

子类对象通过该方法接收信息

public final boolean sendEmptyMessage (int what)

发送一个只含有what值的消息

public final boolean sendMessage (Message msg)

发送消息到Handler,通过handleMessage方法接收

public final boolean hasMessages (int what)

监测消息队列中是否还有what值的消息 public final boolean hasMessages (int what,Objectobject)

监测消息队列中是否还有what值的消息且object属性为制定对象的消息

public final boolean post (Runnable r) 将一个线程添加到消息队列

下面一个倒计时例子

{private Button button;private int count;private Message message;TIME_DESC=0;private Handler handler=new Handler(){(Message msg) {super.handleMessage(msg);switch (message.what){case TIME_DESC:String time= (String) message.obj;button.setText(time);break;}}} ;(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);button= (Button) findViewById(R.id.button);button.setOnClickListener(new View.OnClickListener() {(View v) {count=60;new Thread(new Runnable() {() {while(count>0){count–;try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}message=new Message();message.obj=count+”秒”;message.what=TIME_DESC;handler.sendMessage(message);}}}).start();}});}}

精简一下上面的代码如下

{private Button button;private int count;private Message message;TIME_DESC=0;private Handler handler=new Handler(){(Message msg) {super.handleMessage(msg);switch (message.what){case TIME_DESC:count–;button.setText(count+”秒”);if(count>0){handler.sendEmptyMessage(TIME_DESC);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}break;}}} ;(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);button= (Button) findViewById(R.id.button);//message初始化message=new Message();button.setOnClickListener(new View.OnClickListener() {(View v) {count=60;handler.sendEmptyMessage(TIME_DESC);}});}}Looper简介

Android中的Looper类,是用来封装消息循环和消息队列的一个类,用于在android线程中进行消息处理。handler其实可以看做是一个工具类,用来向消息队列中插入消息的。

只要看得开放得下,何愁没有快乐的春莺在啼鸣,

Android 的消息机制(Handler消息传递机制)

相关文章:

你感兴趣的文章:

标签云: