zoukankan      html  css  js  c++  java
  • Android 用Handler和Message实现计时效果及其中一些疑问

    本来是打算继续做天气预报的优化的,但因为某些原因,我要先把之前做的小应用优化一下。所以今天就插播一下用Handler和Message实现计时效果。

    首先,简要说明一下,这个应用有两个显示数字的Text,一个是显示秒,另一个是显示毫秒,而每10毫秒发送一次Message,让显示毫秒的Text加1,每1000毫秒,也就一秒,就让显示秒的Text加1。此外,还有一个自己制作的圆形进度条,每过一秒会增加6度的弧。这个应用有开始、暂停、重置功能。就是下图这样子:

    一、sendMessage、handleMessage实现跑秒,removeMessages实现暂停

    主要流程是下图这样的:

    说明:

    (1)sendMessage都是延迟发送,也就是sendMessageDelayed。

    (2)invalidate是刷新视图,用来刷新上面提到的圆形进度条。

    详细来讲,就是单击开始按钮,发送第一个Message,然后传到handleMessage中处理,之后便在handleMessage中循环发送Message并处理。而当点击暂停按钮时,就会清除掉消息队列中的消息,也就打破了循环。

    接下来,详细讲讲Message的处理流程这部分,如下图:

     

    说明:

    (1)当有message发送来时,并不会直接添加到MessageQueue中,它需要Looper和Handler对象一起作用,才会添加进去。另外,MessageQueue中的Message是由Looper派遣出去的。

    (2)根据(1)知道,要处理message,必须要有Looper。所以在其它线程执行handleMessage时,必须要创建Looper。因为除了主线程默认有Looper之外,其它线程都是没有的。而每一个Handler实例都会和一个线程和这个线程的MessageQueue关联起来。

    (3)当要在handleMessage里面发送message时,是通过Message.obtain方法获取message对象,这方法是从一个叫公共信息池的地方获取对象的,我的感觉是,这里的对象就是接收到的message。

    (4)在上一张图中,暂停就是调用removeMessages方法。移除掉的就是在MessageQueue中的message。

    我想讲的主要就是上面的那些,以下是开始的那个流程图的代码,:

    效果图,只能是静态的:

    二、一些疑问

    (1)这里的Handler是一个静态类,老师提倡这么写。我之前是这样写的:

    但其实,这么写Android Studio已经有提示了

    我能理解到的就是,如果在主线程中Handler使用Looper或者MessageQueue时,就需要声明Handler为静态类,还有要用上WeakReference弱引用,这么做是为了便于回收。具体是怎样的,还需深入学习。

    (2)用new传入Context的方法创建CircularView(自定义View)的对象,能调用CircularView类的公有方法并修改了其中的成员变量,但就是不能成功调用invalidate刷新方法。

    构造方法是按老师教的修改,但老师并没有演示这样做。构造方法如下图:

    通过打Log输出(图没贴上来),可以知道的确成功调用了自定义View类CircularView中的方法。

    但当我通过findViewById的方法来创建对象时,不仅能调用CircularView类的公有方法并修改了其中的成员变量,还能成功调用invalidate方法。

    对此,我就输出它们俩的对象,看一下,如下图:

    这是通过findViewById的方法来创建的

    这是通过new传入Context方法创建的

    发现它们创建的对象原来是不一样的。我也只能研究到这一步了,所以要深入学习的还有很多啊!

  • 相关阅读:
    FFT学习及简单应用(一点点详细)
    Codeforces 1131 (div 2)
    【NOI2012】魔幻棋盘
    【hdu多校联考第二场】Odd Shops
    【Helvetic Coding Contest 2018】B2. Maximum Control (medium)
    解线性同余方程组
    Math teacher's homework
    【NOIP模拟赛】一道挖掉背景的数学题
    逆向基础-模块隐藏之断链
    解决请求筛选模块被配置为拒绝包含的查询字符串过长的请求
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/7509983.html
Copyright © 2011-2022 走看看