首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Android开发(6) - 初遇Handler

Android开发(6) - 初遇Handler

作者头像
张云飞Vir
发布2020-03-16 15:02:59
发布2020-03-16 15:02:59
5470
举报
文章被收录于专栏:写代码和思考写代码和思考

概述

Handler是线程通讯工具类。用于传递消息。它有两个队列: 1.消息队列 2.线程队列

消息队列使用sendMessage和HandleMessage的组合来发送和处理消息。

线程队列类似一段代码(或者说闭包),或者说一个方法的委托,用户传递方法。使用post,postDelayed 添加委托,使用 removeCallbacks移除委托。

由上面的特性我们可以简单看出“handler类似一个容器对象,它携带了消息的集合和委托的集合”。java里没有委托delegate的概念,但是可以通过class来持有一个可执行的方法代理。

handler更像是一个传递者,在另外的线程里和主线程之间传递消息和可执行的代码。它不仅仅携带了数据,而且封装了一些操作行为,比如说在适当的时机(...)来执行线程队列里的“委托”的代码。

handler可能是和消息队列交互的,我们在new Handler实例化对象时,这个对象应该就和主线程的消息队列建立了关系。当我们使用handler.Post(runnabler1),发送一个委托的方法runnabler1代理给handler时,主消息队列会在适当的时候执行这个runnabler1里的委托方法,即执行了runnabler.run方法。

我们先看个例子:

点击开始后,数字开始从1开始累加

如何实现:

先准备更新视图的代码,如下所示,生命了一个整数 _number ,不断的让这个数字加1,然后设置TextView的SetText为这个数字。 int _number ;

代码语言:javascript
复制
//执行的代码
private Runnable run1 =  new Runnable(){

public void run() {
String text = "";
text = ""+_number++;
_txt1.setText(text);

//再次传递一个Runnable对象,类似产生一种递归效果
_handler.postDelayed(run1,1000);
 }};

上面已经看到 _handler.postDelayed方法了,这个方法就是把 run1这个被委托的内容方法,post传递给hander。主线程会会拿到这个handler,并在适当(空闲)时机执行它。

我们在开始按钮里写启动方法:

代码语言:javascript
复制
    _btn1.setOnClickListener(new OnClickListener(){

 public void onClick(View arg0) {
  //传递一个Runnable对象,1秒后执行该对象的run方法
    _handler.postDelayed(run1,1000);
 }});

在停止按钮里,写停止操作的方法

代码语言:javascript
复制
      _btn2.setOnClickListener(new OnClickListener(){

 public void onClick(View v) {
    //移除回调
      _handler.removeCallbacks(run1);
 }
      });

启动操作:就是把被委托的方法 runnable对象Post出去,即添加到handler的线程队列中去。

停止操作:从线程队列里 移除这个hander

我们还要注意一点,runnabler对象在执行run方法时,再次把自身( ruannabler对象)放进了线程队列,并延迟了1秒,使用了postDelay方法。于是整个就演变成:

1.窗体初始化:构建handler 和runnable对象

2.点击启动按钮,通过handler 发送(post)runnable对象。

3.下面是我的推测:主线程的消息循环能检测到handler 对象的存在,发现它的线程队列里有未执行的 代码(被runnable对象携带),于是主线程取出这个runnabler对 象,执行了它的run方法。 执行后,把这个对象从线程队列里移除。

4.于是我们注意到“在我们写的runnable的run方法里,把自身又再次放到了线程队列”,也就是说,在上一步(第3步)中,刚刚吧 执行后的runnable对象移除,又再次放进去了,于是它会再次执行。由此产生了循环的效果,我们窗体的显示会在这个 移除,和 再次放置之间 更新视图,刷新了界面。于是我们看到视图中数字的递增变化。

5.点击取消按钮,强行将runnable从消息队列里移除,于是run方法不会被再次执行。产生了停止的效果。

我们看到, 将委托的内容runnable对象 发送post后,该对象的run方法会执行。而在执行后,会自动将它移除。所以我们上面多次PostDelay才不会出错,要不然的话,可就执行个没完没了了。

于是我们再次猜测,这里的runnable对象,其实就是个携带方法的委托。hanler会在适当的时机执行它,而在执行它后,会通知系统内核来更新视图,重绘界面。

代码下载

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • 我们先看个例子:
  • 如何实现:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档