为了账号安全,请及时绑定邮箱和手机立即绑定

Android面试常客Handler详解

难度中级
时长 2小时 0分
学习人数
综合评分9.30
169人评价 查看评价
9.7 内容实用
9.3 简洁易懂
8.9 逻辑清晰
  • 更新UI的4种方式: 1.通过Handle的post方法(); 2.调用Handle.sendMessage()方法;传统的方法 3.重写Activity中的runOnUIThread方法更新; 4.调用View自身的post(Runnable run)方法更新;
    查看全部
  • 子线程通过HandlerThread的Looper绑定,在主线程的handler的handleMessage可以向子线程发送消息,子线程的handleMessage也可以向主线程发送消息。
    查看全部
  • 1、Handler是什么? handler是Android给我们提供来更新UI的一套机制,也是一套消息处理的机制,我们可以发送消息,也可以通过塔来处理消息,handler在我们的framework中是非常常见的 2、Handler怎么用? Android在设计的时候,就封装了一套消息的创建、传递、处理机制,如果不遵循这样的机制,就没办法更新UI信息,就会抛出异常信息。
    查看全部
    1 采集 收起 来源:Handler是什么

    2015-05-07

  • 初始化Handler对象时假如传入一个Callback对象,可实现拦截Message消息。 用法:传入Callbak对象时会自动实现一个带布尔返回值的handlerMessage()方法,此方法返回fasle值代表不拦截Message消息,返回true代表拦截,此时,再重写无返回值的handlerMessage()的方法处理消息即可。 拦截消息时,无返回值的handlerMessage()将得不到执行。
    查看全部
  • 主线程与子线程交互 创建两个Handler 主线程中 treadHandler向子线程发送消息 子线程中 handler向主线程发送消息 利用我们的handlerthread线程关联我们的一个子handler,这样的方法比较的好,避免了looper为空的情况。
    查看全部
  • handler负责发送,Looper通过MessageQueue保存接收到的handler消息
    查看全部
  • HandlerThread 解决了多线程并发导致空指针的问题 为什么Handler需要和Looper关联,是因为Handler需要往Looper中的mQeueu里插入Message。所以,如果主线程需要和子线程之间通信,那有两个方法:<br> 1. 主线程拥有子线程的Handler(注意:子线程的Handler需要关联自己的Looper),通过该Handler发送消息即可。<br> 2. 主线程创建一个Handler,但是将子线程的Looper传递给Hander,这样Handler也是往子线程Looper对象的mQueue里插入msg,子线程Looper.loop自然可以拿到主线程消息了。<br> <br> 但是,这两种情况都有弊端。就是线程并发的时候,不能保证子线程的Handler或者Looper对象已经被初始化了。所以这个时候才需要用到HandlerThread 我们可以使用 HandlerThread 模拟异步任务的操作,只需要在主线程中给子线程发送消息,让子线程做耗时操作。 总之,HandlerThread可以处理耗时操作,例如下载网络图片、更新数据库等等,可以在完全不占用主线程的情况下处理比较耗时的操作。从设计的角度来看,是比较方便快捷的。 因为如果自己想要实现异步任务机制,就需要考虑一些问题,例如要开启线程、往异步任务中添加任务,任务本身还要考虑存储结构、什么时候添加任务、什么时候移除任务,以及任务如何传递、派发等等。比较麻烦。 而Android提供了HandlerThread方法,它是系统已经将任务的发送、处理等都封装好了,使用起来比较方便,我们只需调用 HandlerThread。
    查看全部
  • Handler原理的图解。 员工(Handler)要上厕所,需要和领导知会一下(sendMessage),领导(Looper)反馈消息( Looper.loop() )后,“上厕所”这件事还是由员工自己去解决(handleMessage)。 Looper仅仅起了传达消息的作用,而消息的发送和处理都还是由Handler自己去做。
    查看全部
  • Handler与Looper,MessageQueue之间的关系(二)
    查看全部
  • 主要是在HandlerThread里面创建一个Looper,和默认的 handler 进行关联。 所有的handlerMessage()都是在子线程中调用。 我们可以使用 HandlerThread 模拟异步任务的操作,只需要在主线程中给子线程发送消息,让子线程做耗时操作。 总之,HandlerThread可以处理耗时操作,例如下载网络图片、更新数据库等等,可以在完全不占用主线程的情况下处理比较耗时的操作。从设计的角度来看,是比较方便快捷的。 因为如果自己想要实现异步任务机制,就需要考虑一些问题,例如要开启线程、往异步任务中添加任务,任务本身还要考虑存储结构、什么时候添加任务、什么时候移除任务,以及任务如何传递、派发等等。比较麻烦。 而Android提供了HandlerThread方法,它是系统已经将任务的发送、处理等都封装好了,使用起来比较方便,我们只需调用 HandlerThread。
    查看全部
  • 以下内容来自大神笔记: handler、looper、messagequeue、message四者可以这样理解: handler:工人; looper:传送带移动的动力; messagequeue:传送带; message:传送带上面的产品。 工人(handler)把自己的产品(message)放在传送带(messagequeue)尾部,在动力(looper)作用下,传送带向前移动,最终产品到达传送带头部,被取出来处理(handmessage())。 ----------------- 先要有个概念。 1、handler 消息处理器,负责处理消息。 2、Message 消息,包含消息id,被处理的对象。 3、MessageQueue 消息队列,存放Handler发送过来的Message 4、looper 消息泵,不间断的从MessageQueue消息队列中抽取消息。 简单的比喻looper就是水泵,MessageQueue储水的池塘,Message就是水,Handler就是操作的人。
    查看全部
  • 如图,真正判断当前线程是否在UI线程进行更新操作的核心代码就是图中的蓝色部分。 通过 ViewParent对象的 invalidateChild()方法做出判断。 ViewParent 是 ViewRootImpl 的实现类。 ViewRootImpl 主要用于更新 UI 的判断处理逻辑。它的初始化是在Activity的onResume()方法中进行。 我们做了个小例子:在子线程中更新TextViwe,也就是更新UI: new Thread(){ @Override public void run() { textView.setText("在非主线程中更新UI"); } }.start(); 会发现系统并不会报错,原因是 ViewParent 对象的 invalidateChild()方法还没来得及做出判断!为什么来不及? 因为“检查当前线程是否是主线程”的操作是在onResume()方法中,该方法在onCreate()之后调用,所以存在极为短暂的时间是无法做出检查的,就在这段时间内通过非主线程更新UI,系统也无法报错。 虽然可以在非主线程中更新 UI ,但是不建议这么做,因为这样的做法是有隐患的。 --------------- 摘自评论区: 在ViewRootImpl没有实例化的时候是不会check是否是主线程,也就是说,在非UI线程中是可以更新UI的,但是为了线程安全的原因,系统会强制要求只能在主线程中更新UI(猜测)。之所以说没有太大的意义是因为实际开发中是不会有这种情况的,谷歌官方也是说了只能在UI线程更新UI,这顶多算是一个BUG吧。 回调的路径: text.setText()-->checkForRelayout()-->invalidate()-->ViewParent.invalidateChild()-->invalidateChildInParent()-->checkThread()
    查看全部
  • 代码实现: 1.使用Handler的post(): public void handlerChangeUI(){ handler.post(new Runnable(){ @Override public void run() { textView.setText("OK"); } }); } 2. 使用Handler的sendMessage(): public void handlerChangeUI2(){ handler.sendEmptyMessage(1); } 3. 使用Activity的runOnUiThread(): public void activityUpdateUI(){ runOnUiThread(new Runnable() { @Override public void run() { textView.setText("Changed by Activity"); } }); } 4. 使用View的 post(): public void viewUpdateUI(){ textView.post(new Runnable() { @Override public void run() { textView.setText("UI was updated by view.post"); } }); } 最后在 onCreate()内部创建一个线程,依次调用如上四种方法,观察结果。 new Thread(){ @Override public void run() { try { Thread.sleep(1000); // handlerChangeUI(); // handlerChangeUI2() // activityUpdateUI() viewUpdateUI(); } catch (InterruptedException e) { e.printStackTrace(); } } }.start();
    查看全部
  • 如图蓝色选中区域,主线程的 handler 使用其他线程的 looper,运行时会报出空指针异常,程序崩溃。 为什么呢?这涉及到多线程并发问题。当主线程已经运行到图示蓝色选中区域时,可能其他线程(这里是thread线程)还没有创建或者初始化 looper。于是就造成了空指针异常。 如何解决多线程导致的空指针问题? 使用HandlerThread。
    查看全部
  • 摘自评论区: handler、looper、messagequeue、message四者可以这样理解:handler:工人;looper:传送带移动的动力;messagequeue:传送带;message:传送带上面的产品。工人(handler)把自己的产品(message)放在传送带(messagequeue)尾部,在动力(looper)作用下,传送带向前移动,最终产品到达传送带头部,被取出来处理(handmessage())。 ----------------- 先要有个概念。 1、handler 消息处理器,负责处理消息。 2、Message 消息,包含消息id,被处理的对象。 3、MessageQueue 消息队列,存放Handler发送过来的Message 4、looper 消息泵,不间断的从MessageQueue消息队列中抽取消息。 简单的比喻looper就是水泵,MessageQueue储水的池塘,Message就是水,Handler就是操作的人。
    查看全部

举报

0/150
提交
取消
老师告诉你能学到什么?
通过本课程,你将学到: 1、什么是Handler 2、如何使用Handler 3、Handler的原理是什么 4、如何定义一个与线程相关的Handler 5、Android更新UI的几种方式 6、非UI线程真的不能更新UI吗 7、Handler使用过程中遇到的问题

微信扫码,参与3人拼团

意见反馈 帮助中心 APP下载
官方微信
友情提示:

您好,此课程属于迁移课程,您已购买该课程,无需重复购买,感谢您对慕课网的支持!