手记

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

本文包括与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

1人推荐
随时随地看视频
慕课网APP