Android学习笔记48:使用Handler实时更新UI

在Android中,主要通过MessageQueue、Looper和Handler三个类来实现Android应用程序的消息处理。其中,MessageQueue类用来描述消息队列;Looper类用来创建消息队列,以及进入消息循环;Handler类则用来发送消息和接收消息。

  本文将主要对Handler进行简要介绍,并以一个简单的实例演示如何使用Handler实时更新UI。

1.Handler的作用

  在Android中,当应用程序启动时,Android系统会启动一个主线程(也被称为UI线程),主要用来管理界面中的UI控件,对用户操作进行实时响应。如果我们在UI线程中进行一项非常耗时的操作,比如点击Button按钮,进行文件上传或下载,那么在这段时间内界面会出现假死现象(不响应用户操作),这显然是用户体验极差的。更为严重的是,如果在5秒内这个耗时的操作还未结束的话,Android系统会进行错误提示“强制关闭”。

  所以通常的做法是启动一个子线程,然后在子线程中来完成这些比较耗时的操作。但是,如果我们想要在子线程中更新UI,那又该如何做呢?

  因为在Android中,更新UI只可以在主线程中进行,所以想要在子线程中更新UI,就必须得子线程通知主线程,然后主线程来更新UI。

  这一过程正是通过Handler来实现的。

  子线程可以通过两种方式与Handler进行通信:Message和Runnable。使用Message可以从子线程中传递一些参数给主线程,Handler获取这些信息并进行相应的处理。使用Runnable则可以直接执行某个处理结果。其实,这两者的实质都是在Handler的队列中放入内容,Handler会处理完一个消息或者执行完某个处理之后再进行下一步操作,这样就不会出现多个线程同时要求进行UI处理而引发混乱现象。

2.Handler的常用方法

  Handler的消息队列中的内容(Message或Runnable)可以设置为马上执行,延迟一定时间再执行或者指定在某个时刻执行。此外,还可以指定将其放在队列的头部,表示该内容具有最高优先级别,立刻执行。

  这些要求的设置可以通过以下一些函数来实现:

  (1)post(Runnable r);

  (2)postAtTime(Runnable r, long uptimeMillis);

  (3)postDelayed(Runnable r, long uptimeMillis);

  (4)postAtFrontOfQueue(Runnable r);

  (5)sendEmptyMessage(int what);

  (6)sendMessage(Message msg);

  (7)sendMessageAtTime(Message msg, long uptimeMillis);

  (8)sendMessageDelayed(Message msg, long uptimeMillis);

  (9)sendMessageAtFrontOfQueue(Runnable r);

3.实例

  在本实例中,我们创建了一个Web工程,该Web工程很简单,仅仅是获取系统的当前时间,然后显示出来而已。

  在Tomcat上运行该Web工程,能够看到如图1所示的运行效果。

图1 Web工程运行效果

  该页面是通过一个简单的date.jsp文件来实现的。

  我们现在要做的就是,在Android工程中,通过一个TextView来显示当前页面的内容,并且在子线程中每隔1秒钟,发送一个Message给Handler,Handler收到Message通知后,完成刷新UI的操作。

  下面就来说说每一步的具体实现。

3.1在主线程中启动一个子线程

  首先,我们需要在主线程中启动一个子线程,这个比较简单,直接在MainActivity的onCreate()方法中调用如下方法即可:

  new Thread(mRunnable).start();

3.2在子线程中发送Message给Handler

  在创建子线程时,我们使用了Runnable接口对象mRunnable。这里,只需要实现Runnable接口,并重写该接口的run()方法,在run()方法中实现每1秒发送一条Message给Handler即可。具体实现方法如下:

 1     /*
 2      * Function   :   实现run()方法,每1秒发送一条Message给Handler
 3      * Author     :   博客园-依旧淡然
 4      */
 5     private Runnable mRunnable = new Runnable() {
 6         public void run() {
 7             while(true) {
 8                 try {
 9                     Thread.sleep(1000);
10                     mHandler.sendMessage(mHandler.obtainMessage());
11                 } catch (InterruptedException e) {
12                     e.printStackTrace();
13                 }
14             }
15         }
16     };

3.3Handler接收Message通知

  最后,我们创建一个Handler对象,用来接收Message通知。在收到Message通知后,完成刷新UI的操作即可。具体实现方法如下:

 1     /*
 2      * Function   :   实现handleMessage()方法,用于接收Message,刷新UI
 3      * Author     :   博客园-依旧淡然
 4      */
 5     private Handler mHandler = new Handler() {
 6         public void handleMessage(Message msg) {
 7             super.handleMessage(msg);
 8             refreshUI();
 9         }
10     };

3.4刷新UI

  由以上的代码可以看出,刷新UI的操作,我们是放在refreshUI()方法中来完成的。refreshUI()方法的实现也很简单,调用HttpUtils工具类中的getInputStream()方法,获得图1所示Web工程的页面内容输入流,再将该输入流转化为字符串,放入TextView控件中进行显示即可。具体实现方法如下:

 1     /*
 2      * Function   :   刷新UI
 3      * Author     :   博客园-依旧淡然
 4      */
 5     private void refreshUI() {
 6         try {
 7             InputStream inputStream = HttpUtils.getInputStream();
 8             String resultData = HttpUtils.getResultData(inputStream);
 9             mTextView.setText(resultData);
10         } catch (IOException e) {
11             e.printStackTrace();
12         }
13     }

3.5实例效果

  最后,运行该Android工程,运行效果如图2所示,可以看到,当前时间每隔1秒会刷新一次,能够始终保持与图1所示页面的时间同步。

图2 运行效果

Android学习笔记48:使用Handler实时更新UI

时间: 2024-10-17 05:19:34

Android学习笔记48:使用Handler实时更新UI的相关文章

android学习笔记25——事件处理Handler

Handler消息传递机制 ==> android消息机制是另一种形式的“事件处理”,这种机制主要是为了解决android应用的多线程问题. ——android平台不允许Activity新启动的线程访问该Activity里的界面组件,这样就导致新启动的线程无法动态改变界面组件的值. 但实际android应用开发中,尤其是涉及动画游戏开发中,需要让新启动的线程周期性地改变界面组件的值,就需要借助Handler消息传递机制处理. Handler类的主要作用: 1.在新启动的线程中发送消息: 2.在主

Android学习笔记(四九):通过Content Provider访问数据

在上次笔记中,我们编写了自己的Provider,这次笔记,我们将通过Content Provider的Uri接口对数据进行访问,重写Android学习笔记(四二)中例子.在这里我们不在充分描述相关UI如何编写,可以到笔记(四二)中详细查看,重点讲述如何实现数据的访问. 读取信息 读取信息方式,在笔记(四七)中已经介绍,代码如下 private voidread(){     /* 通过managedQuery读取,第1参数表示URI, 第2参数表示所需读取的信息,第3个参数是限制条件,类似SQL

Android学习笔记(四六):互联网通信-文件下载

在Android 2.3引入了DownloadManager可以处理复杂的文件下载,包括检查用户是否有数据联系(WIFI或者移动数据),当用户从一个有数据连接的地方移动到无连接的地方(例如离开了wifi或者3G data的access point),确保设备在下载过程中保持awake状态.DownloadManager可以处理HTTP URLs,但是不能处理HTTPS(SSL) URLs. 设置下载文件条件许可 在这个例子,将学习通过DownloadManager从Internet下载文件,并存

Android学习笔记二

17. 在ContentProvider中定义的getType()方法是定义URI的内容类型. 18. SQLiteDatabase类中的insert/delete/update/query方法其实也挺好用的,我在EquipmentProvider类中做了实现 19. Android专门有个单元测试项目(Android Test Project),在这个项目中,可以新建一个继承AndroidTestCase类的具体测试类来单元测试某个功能.我新建了一个AndroidTestProject项目,在

十一、Android学习笔记_AsyncQueryHandler的应用

研究AsyncQueryHandler这个类的时候遇到了几个重要的不清楚的知识点 1. Handler与Thread,Looper的关系 2. HandlerThread是干什么用的 3. ThreadLocal类是干什么用的 Handler 主要是用来发送和处理消息,但是发送了消息后,消息是怎么传递的呢?这就是Looper的作用了,每个Handler中都会有一个Looper对象,如果在创建Handler的时候不指定,系统就会默认将当前线程的Looper绑定到Handler上,Looper对象中

Android学习笔记五之Service

Android学习笔记五之Service 1.什么是Service? 什么是Service?Service是Android系统的四大组件之一,官方文档是这样描述Service的: A Service is an application component that can perform long-running operations in the background and does not provide a user interface. Another application comp

udacity android 学习笔记: lesson 4 part b

udacity android 学习笔记: lesson 4 part b 作者:干货店打杂的 /titer1 /Archimedes 出处:https://code.csdn.net/titer1 联系:1307316一九六八 声明:本文採用下面协议进行授权: 自由转载-非商用-非衍生-保持署名|Creative Commons BY-NC-ND 3.0 ,转载请注明作者及出处. tips:https://code.csdn.net/titer1/pat_aha/blob/master/Mar

Pro Android学习笔记(十二):了解Intent(下)

解析Intent,寻找匹配Activity 如果给出component名字(包名.类名)是explicit intent,否则是implicit intent.对于explicit intent,关键就是component 名字,在<intent-fliter>中声明的其他属性被忽略.对于implicit intent,则根据action,category和data来进行匹配.然而一个intent fliter中可以声明多个actions,多个categories,多个data属性,因此可以满

Android学习笔记(四五):互联网通信-HttpClient、XML解析(W3C)

前几日Android发布了4.0 Icecream,昨天上网发现Begining Book中有Edition 3的版本,比对一下,还是有相当的改动,不仅仅增加了tablet的部分,对原有的章节有有一些修订,前后的调整等等.先按Edtion 2的顺序看,相同章节的看Edtion 3,然后回头看Edition 3的Chapter 24.25(E2的36).26.27.28.29.44.45.46.47几个新增章节.同时将模拟器改为Android 2.3的版本,已适应可能新增的改动. 访问Intern