继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

子线程中创建Handler可以吗?(上)

龙西岳
关注TA
已关注
手记 7
粉丝 14
获赞 101

本文包括与Handler有关的以下问题:

  (1)Handler的作用

  (2)为什么Android中要设计为只能在UI线程中去更新UI呢?

  (3)Handler的两个异常

  (4)Handler、Looper MessageQueue之间的关系(源码角度)

  (5)跟线程相关的Handler,即HandlerThread(源码角度分析)

  (6)主线程往子线程发消息

一、Handler的作用:

(1)在非UI线程中完成耗时操作,在UI线程中去更新UI。

(2)可以在主线程中发送延时消息。

二、为什么Android中要设计为只能在UI线程中去更新UI呢?

(1)解决多线程并发问题(根本原因)

(2)提高界面更新的性能问题

(3)架构设计的简单

你可能会说,既然是担心多线程并发问题,那我在子线程中加锁进行更新UI行不行呢?你这样想的话,会容易造成UI卡顿的,而且性能也不好。

注1:大部分面试者很难去说出一个令面试官满意的答案。

注2:关于多线程,这里举一个例子,比如说银行取款的问题。正常情况下,银行卡余额不能少于取款金额,如果多线程进行取款的话,就会造成线程不安全。

注3:Android中之所以说架构简单,是因为帮我们封装了很多更新UI的操作。

三、Handler的两个异常:

在使用Handler时,经常会出现以下两个异常:

(1)CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views:此异常是因为尝试在子线程中去更新UI,进而报错。

(2)Can’t create handle inside thread that ha not called Looper.prepared:是因为我们在子线程中去创建Handler,而产生的异常。

我们接下来通过代码来把这两个异常演示一下。

1、子线程中更新UI的异常:

(1)activity_main.xml:
图片描述
上方代码中,一个文本,一个按钮,代码比较简单。
(2)MainActivity.java:
图片描述
上方代码中,核心代码是第45行:点击按钮后,在子线程中更新UI。
我们来看一下后台的log日志:
图片描述
上图中报的错误日志就是因为我们在子线程中去更新UI。
解决方案:
  在子线程中创建Message消息,通过Handler发给主线程,之后在Handler的handleMessage方法中获得Message消息,进而处理更新UI界面。代码如下:
图片描述
上方第50行代码也可以换成51行代码:

2、在子线程中创建Handler的异常:

MainActivity.java:
图片描述
运行程序后, 报错如下:
图片描述

非原创,参考自:http://blog.csdn.net/erliangcode/article/details/52117831

打开App,阅读手记
1人推荐
发表评论
随时随地看视频慕课网APP