• 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 运行效果

     

     

    作者:依旧淡然
    邮箱:menlsh@163.com
    本文版权归作者所有,未经作者同意,严禁转载及用作商业传播,否则将追究法律责任。
  • 相关阅读:
    Kubernetes
    桥接模式
    原型模式
    工厂模式
    生成器模式
    Java-Sentinel限流中间件
    python模拟发送、消费kafka消息
    使用idea搭建springBoot项目
    linux 虚拟机不能启动不了系统,虚拟机更改linux初始启动5,出现无法启动现象
    vwware workstation虚机网络配置NAT
  • 原文地址:https://www.cnblogs.com/menlsh/p/3125341.html
Copyright © 2020-2023  润新知