zoukankan      html  css  js  c++  java
  • android 在子线程中使用handler更新界面

    1. 在子线程中创建一个handler对象,让这个handler对象获取主线程的looper,这样才能把这个handler中的消息发送到ui线程的消息队列中

    下面这个界面当点击updateui按钮就会创建一个对象然后调用它的更新图片和文字的方法,这两个设置方法在子线程中执行。

    在更新界面的对象的类中创建一个handler对象,在初始化的时候给他赋值为Looper.getMainLooper,这样这个handler分发的消息就会被分发到主线程的队列中并且被执行,所以就能在这个子线程中进行更新界面了,如果在updateui0这个方法中不适用mhandler来提交更新的话就会发生下面的错误

    android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

     2. handler源代码分析

    首先是创建handler对象的时候我们传入了ui线程的looper到这个子线程的handler中。可以看到looper被赋值给了handler对象中的mLooper,并且由于我们只是用了带looper参数的构造器,所以这里的callbak是为null

    2.在handler的post方法中通过getMessage方法获取一个msg对象,这个对象初始化就带有了post提交的那个runnable对象,这样这个msg就持有了我们要提交到ui线程进行更新的runnable对象了

     3. post继续回调用到sendMessageAtTime方法,这个方法会创建一个消息队列,这个消息队列就是我们在handler创建时传递进去的looper所携带的消息队列(这里是ui线程的消息队列),这里的mQueue是在handler中获取的looper的queue

    然后将mQueue赋值一下再传递到enqueueMessage中去,这个传递的messagequeue其实是来自ui线程的

    4. 把消息队列和消息都传递到了enqueueMessage方法中,这个方法就会调用这个handler中的消息队列对象,通过消息队列对象的enqueueMessage方法会循环取出消息队列中的消息进行处理

     综上所述,通过handler和looper旧可以进行线程间的通信。通过获取主线程的looper对象,就可以在子线程的handler中提交更新界面的代码了。

  • 相关阅读:
    BZOJ 1391: [Ceoi2008]order
    BZOJ 4504: K个串
    2019 年百度之星·程序设计大赛
    POJ 2398 Toy Storage (二分 叉积)
    POJ 2318 TOYS (二分 叉积)
    HDU 6697 Closest Pair of Segments (计算几何 暴力)
    HDU 6695 Welcome Party (贪心)
    HDU 6693 Valentine's Day (概率)
    HDU 6590 Code (判断凸包相交)
    POJ 3805 Separate Points (判断凸包相交)
  • 原文地址:https://www.cnblogs.com/xxss0903/p/5959046.html
Copyright © 2011-2022 走看看