| 副标题[/!--empirenews.page--] 我们在日常开发中,总是不可避免的会用到 Handler,虽说 Handler 机制并不等同于 Android 的消息机制,但 Handler 的消息机制在  Android 开发中早已谙熟于心,非常重要! 
 通过本文,你可以非常容易得到一下问题的答案: 
    Handler、Looper、Message 和 MessageQueue 的原理以及它们之间的关系到底是怎样的?MessageQueue 存储结构是什么?子线程为啥一定要调用 Looper.prepare() 和 Looper.loop()? Handler 的简单使用 相信应该没有人不会使用 Handler 吧?假设在 Activity 中处理一个耗时任务,需要更新 UI,简单看看我们平时是怎么处理的。 override fun onCreate(savedInstanceState: Bundle?) {  super.onCreate(savedInstanceState)  setContentView(R.layout.activity_main3)  // 请求网络  subThread.start() } override fun onDestroy() {  subThread.interrupt()  super.onDestroy() } private val handler by lazy(LazyThreadSafetyMode.NONE) { MyHandler() } private val subThread by lazy(LazyThreadSafetyMode.NONE) { SubThread(handler) } private class MyHandler : Handler() {  override fun handleMessage(msg: Message) {  super.handleMessage(msg)  // 主线程处理逻辑,一般这里需要使用弱引用持有 Activity 实例,以免内存泄漏  } } private class SubThread(val handler: Handler) : Thread() {  override fun run() {  super.run()  // 耗时操作 比如做网络请求  // 网络请求完毕,咱们就得哗哗哗通知 UI 刷新了,直接直接考虑 Handler 处理,其他方案暂时不做考虑  // 第一种方法,一般这个 data 是请求结果解析的内容  handler.obtainMessage(1,data).sendToTarget()  // 第二种方法  val message = Message.obtain() // 尽量使用 Message.obtain() 初始化  message.what = 1  message.obj = data // 一般这个 data 是请求结果解析的内容  handler.sendMessage(message)  // 第三种方法  handler.post(object : Thread() {  override fun run() {  super.run()  // 处理更新操作  }  })  } } 
 上述代码非常简单,因为网络请求是一个耗时任务,所以我们新开了一个线程,并在网络请求结束解析完毕后通过 Handler 来通知主线程去更新 UI,简单采用了  3 种方式,细心的小伙伴可能会发现,其实第一种和第二种方法是一样的。就是利用 Handler 来发送了一个携带了内容 Message  对象,值得一提的是:我们应该尽可能地使用 Message.obtain() 而不是 new Message() 进行 Message 的初始化,主要是  Message.obtain() 可以减少内存的申请。 受到大家在前面文章提出的建议,我们就尽量地少贴一些源码了,大家可以直接很容易发现,上述的所有方法最终都会调用这个方法: public boolean sendMessageAtTime(Message msg, long uptimeMillis) {  MessageQueue queue = mQueue;  if (queue == null) {  RuntimeException e = new RuntimeException(  this + " sendMessageAtTime() called with no mQueue");  Log.w("Looper", e.getMessage(), e);  return false;  }  return enqueueMessage(queue, msg, uptimeMillis); } private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {  msg.target = this;  if (mAsynchronous) {  msg.setAsynchronous(true);  }  return queue.enqueueMessage(msg, uptimeMillis); } 
 上面的代码出现了一个 MessageQueue,并且最终调用了 MessageQueue#enqueueMessage  方法进行消息的入队,我们不得不简单说一下 MessageQueue 的基本情况。 MessageQueue (编辑:宣城站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |