如果在需要在Activity中一个耗时的操作,例如当我们需要联网读取数据, 或者读取本地较大的一个文件的时候,不能把这些操作放在主线程中。因为如果 放在主线程中的话,界面会出现假死现象, 如果5秒钟还没有完成的话,会收到 Android系统的一个错误提示 "强制关闭"。这个时候我们需要把这些 耗时的操作,放在一个子线程中,因为子线程涉及到UI更新,Android主线程是 线程不安全的,也就是说,更新UI只能在主线程中更新,子线程中操作是危险的 。这个时候,Handler就出现了,来解决这个复杂的问题。Handler主要接受子线 程发送的数据, 并用此数据配合主线程更新UI。 ,由于Handler运行在主线程中 (UI线程中),它与子线程可以通过Message对象来传递数据,这个时候,Handler 就承担着接受子线程传过来的(子线程用sedMessage()方法传递)Message对象(里 面包含数据),把这些消息放入主线程队列中,配合主线程进行更新UI。Handler 就是运行在Activity中的不可见的控件,它包括一个可以容纳主线程的子线程的 队列容器以及一个子线程和主线程通信的Message消息队列容器。Handler可以把 线程对象装入线程队列,也可以从线程队列中取出线程执行。
Handler的基本使用方法:
post(Runnable) 将线程对象添加到队列中
postAtTime(Runnable,long) 在指定的时间( uptimeMillis )执行 Runnable 对象
postDelayed(Runnable,long) 在指定的时间间隔( delayMillis )后执行 Runnable 对象
Handler使用的一般步骤为:
1. 首先在Activity中声明一个Handler对象。
2. 定义一个或多个线程对象,复写线程对象的run()方法,在run()方法中写 上想要执行的操作。
3. 用Handler的post()(post()有多种重载形式)方法线程对象装入handler 的线程队列。系统会在适当的时候取出当前线程队列中的队首线程并执行。
4. 当需要停止线程队列中某个线程的执行时,可以在主线程中调用 removeCallbacks()方法,删除队列中未执行的线程对象。
示例:新建一个Android应用程序项目,main.xml总添加两个Button按钮。程 序的流程为当我们点击Activity中的start按钮时,Activity中的Handler对象会 将一个线程对象updateThread装入线程队列,在这个线程中会在控制台输出 “updateThread”,并且将本线程再次装入handler的线程队列,形成循环调用 。这样就可以不断输出文字内容。当我们单击end按钮时调用removeCallbacks() 方法,删除线程对象,停止线程的执行,不再输出文字内容。
main.xml
01.<?xml version="1.0" encoding="utf-8"? >
02.<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"03. android:orientation="vertical"
04. android:layout_width="fill_parent"
05. android:layout_height="fill_parent"
06. >
07.<TextView
08. android:layout_width="fill_parent"
09. android:layout_height="wrap_content"
10. android:text="@string/hello"
11. />
12.<Button
13. android:id="@+id/startButton"
14. android:layout_width="300dp"
15. android:layout_height="wrap_content"
16. android:text="start"
17. />
18.<Button
19. android:id="@+id/endButton"
20. android:layout_width="300dp"
21. android:layout_height="wrap_content"
22. android:text="end"
23. />
24.</LinearLayout>