Handler主要用于异步消息处理。Android中以此作为子线程和主线程通信的桥梁,从而实现对UI(主线程)的内容的更新。

背景:Android中的主线程主要管理界面中的UI控件以及进行事件的分发。但UI控件的操作并没有被设计成线程安全,所以需要主线程对界面进行统一的管理,这也就是所说的单线程模型。所以在主线程中就不应该进行耗时的任务操作,这样容易造成界面的卡顿或ANR的产生。而是应该将这些任务放在子线程中进行,然后把处理后的结果通过Handler传递给主线程进行界面显示的更新。

工作原理

Android Handler 小结_第1张图片

MessageQueue:消息队列。由Looper所持有和创建。队列结构,FIFO,存放由Handler添加过来的消息和对象,然后被Looper依次取出给Handler进行消费。

Looper:实现消息的循环和分发。主线程在初始化时会默认调用Looper.prepare()和Looper.loop()创建和关联消息队列,并创建消息循环。而在子线程中需要创建Handler时,需主动去实现这个初始化过程。

Handler:发送和处理消息和对象。通过sendMessage发送消息和post传递Runnable对象,Looper在消息队列中取出消息并分发给Handler,然后在handleMessage方法中执行。

分发消息的主要方法:
post(Runnable)、postAtTime(Runnable,long)、postDelayed(Runnable long)、
sendEmptyMessage(int)、sendMessage(Message)、
sendMessageAtTime(Message,long)、sendMessageDelayed(Message,long)

使用注意

1、非静态内部类的使用。在Activity退出时,非静态内部类和匿名内部类会持有其引用,当消息发生延迟时,容易使得该Activity很多资源不被回收,从而引起内存泄露。所以建议直接使用静态内部类并结合弱引用来使用,也可以将Handler类单独出来实现。

2、消息延迟。和1所诉的情形一样,消息在Acitivity退出时仍在消息队列中,未被消费,此时就容易引起内存泄露的问题,所以可以在Acitivity退出时调用handler的removeCallbacks移除runnable和removeMessages移除message,从而移除在消息队列等待的未被消费的消息。

代码例子:

private static class InnerHandler extends Handler {        private final WeakReference mActivity;        public InnerHandler(BaseActivity _activity)         {            mActivity = new WeakReference(_activity);        }        @Override        public void handleMessage(Message msg) {            // TODO Auto-generated method stub            if (mActivity.get() != null)            {                // Update UI            }        }    }

更多相关文章

  1. Android Handler消息队列的实现原理
  2. 【android】手写一套Java的Handler程序,深入理解Android消息机制
  3. android异步线程利用Handler将消息发送至UI线程
  4. Android消息机制原理,仿写Handler Looper源码跨线程通信原理--之
  5. Android日志消息的生成详细步骤
  6. Android应用程序键盘(Keyboard)消息处理机制分析(16)
  7. Android创建子线程和回调主线程的几种方式

随机推荐

  1. 微信支付奇葩问题 system:access_denied
  2. Android栗子の图片验证码生成实例代码
  3. Android应用界面开发——第二周笔记
  4. Android 设置EditText不显示光标
  5. App启动(一)Application的创建
  6. Android init进程
  7. Android中的进程有哪些?说出它们的优先级
  8. JS或TS调用原生Android的方法
  9. Android不继承ViewPager实现自动滚动翻页
  10. android getContext(),Context