当前位置: 首页 > news >正文

/使用匿名内部类来复写Handler当中的handlerMessage()方法

例2会导致updateThread的run方法死循环,原因如下:
当i==100时,执行了下面几行代码
if (i == 100){  
                //将线程对象从队列中移除  
                updateBarHandler.removeCallbacks(updateThread);   
    } 
看似updateThread线程从线程对象队列中移除,不会再执行了,但是执行这几行代码前执行了下面代码
//将Message对象加入到消息队列当中  
updateBarHandler.sendMessage(msg); 
这会导致下面的代码被执行
public void handleMessage(Message msg) {     
            progressBar.setProgress(msg.arg1);     
           updateBarHandler.post(updateThread);    //将要执行的线程放入到队列当中     
}
updateThread线程又加到线程对象队列中,updateThread线程永远不会从线程对象队列中移除,updateThread的run方法不断的执行,这就导致了死循环。

解决方案:
将 updateThread的run方法里的
if (i == 100){  
                //将线程对象从队列中移除  
                updateBarHandler.removeCallbacks(updateThread);   
    } 
这几行代码移到updateBarHandler的handleMessage方法里,修改如下:
Handler updateBarHandler = new Handler(){  
        @Override  
        public void handleMessage(Message msg) {  
            progressBar.setProgress(msg.arg1);  
            if(msg.arg1==100){
                       updateBarHandler.removeCallbacks(updateThread);   
            }else{
                      updateBarHandler.post(updateThread);    //将要执行的线程放入到队列当中
            }  
        }  
    };  

我是通过调试查看代码的执行顺序,发现这个问题的
9 楼  jkzhao 2012-10-27  
Handler主要是用于子线程与主线程的通讯,子线程可以把消息发送到主线程的Looper,有主线程来处理。
8 楼  tracydeerge 2012-10-25  
我觉得Handler大多用来作为线程池中的线程与主线程的通信工具!
7 楼  416849838 2011-11-25  
回答三楼  不行,因为不能在子线程里更新UI
6 楼  zhangjm123 2011-11-20  
将 //如果i的值等于100  
            if (i == 100){  
                //将线程对象从队列中移除  
                updateBarHandler.removeCallbacks(updateThread);   
            }  
删了,写到如5楼写的那样就行了!!
5 楼  sserf 2011-09-28  
不错,很全面,转了!
4 楼  cj83226 2011-09-05  
Java代码   收藏代码
  1. if(msg.arg1>=progressBar.getMax())   
  2.             {    
  3.                 System.out.println("removeCallbacks");  
  4.                 updateBarHandler.removeCallbacks(updateThread);        
  5.                 
  6.             }  
  7.             else {    
  8.                 System.out.println("updateBarHandler.post");  
  9.                 updateBarHandler.post(updateThread);    //将要执行的线程放入到队列当中  
  10.             }  

应该是这样吧。。。。
3 楼  wjb_forward 2011-03-24  
请问直接在run方法里面增加进度条的进度不行吗,把i写成一个全局变量。
2 楼  meng_fan_zhen 2011-03-16  
hehez 写道
Java代码   收藏代码
  1. //使用匿名内部类来复写Handler当中的handlerMessage()方法     
  2.     Handler updateBarHandler = new Handler(){     
  3.         @Override    
  4.         public void handleMessage(Message msg) {     
  5.             progressBar.setProgress(msg.arg1);    
  6.  if(msg.arg1<=progressBar.getMax()) {  
  7. updateBarHandler.removeCallbacks(updateThread);      
  8.   
  9.            }else {  
  10. updateBarHandler.post(updateThread);    //将要执行的线程放入到队列当中     
  11.   
  12. }  
  13.         }     
  14.    };  



我试了下,这个是好使的。 


1楼的判断条件是不是正好写反了?
1 楼  hehez 2011-03-04  
Java代码   收藏代码
  1. if (i == 100){     
  2.                 //将线程对象从队列中移除     
  3.                updateBarHandler.removeCallbacks(updateThread);      
  4.             }     


就这段,我也出现和你一样的状况。我在网上搜了好多,有人说是,removeCallbacks只是把updateThread这个线程从队列中移除,但是并没有停止线程。 
然后网上也有人提供了一个修正方法,就是在下面这段代码中间 

Java代码   收藏代码
  1. //使用匿名内部类来复写Handler当中的handlerMessage()方法     
  2.     Handler updateBarHandler = new Handler(){     
  3.         @Override    
  4.         public void handleMessage(Message msg) {     
  5.             progressBar.setProgress(msg.arg1);     
  6.            updateBarHandler.post(updateThread);    //将要执行的线程放入到队列当中     
  7.         }     
  8.    };  


添加一个判断 

Java代码   收藏代码
  1. //使用匿名内部类来复写Handler当中的handlerMessage()方法     
  2.     Handler updateBarHandler = new Handler(){     
  3.         @Override    
  4.         public void handleMessage(Message msg) {     
  5.             progressBar.setProgress(msg.arg1);    
  6.  if(msg.arg1<=progressBar.getMax()) {  
  7. updateBarHandler.removeCallbacks(updateThread);      
  8.   
  9.            }else {  
  10. updateBarHandler.post(updateThread);    //将要执行的线程放入到队列当中     
  11.   
  12. }  
  13.         }     
  14.    };  



我试了下,这个是好使的。 

转载于:https://www.cnblogs.com/tfy1332/p/3653588.html

相关文章:

  • linux启动过程
  • 超赞的CSS3进度条 可以随进度显示不同颜色
  • 升级Ubuntu 12.04下的gcc到4.7
  • ASP.NET MVC 5 - 查询Details和Delete方法
  • checkboxlist 横向显示,自动换行
  • 本季度学习内容
  • 两个线程交替打印字符串
  • rpm包制作
  • 指针数组和指向指针的指针
  • 破碎吧,
  • Permission denied You (root) are not allowed to access to (crontab) because of pam configuration.
  • PAT 1064
  • 最大堆最小堆总结
  • Windows Server 2012 R2工作文件夹⑨:自动发现设置
  • linux下ntp时间服务器搭建
  • canvas绘制圆角头像
  • CentOS学习笔记 - 12. Nginx搭建Centos7.5远程repo
  • CSS盒模型深入
  • JavaScript设计模式与开发实践系列之策略模式
  • JavaSE小实践1:Java爬取斗图网站的所有表情包
  • JavaWeb(学习笔记二)
  • Java比较器对数组,集合排序
  • npx命令介绍
  • oldjun 检测网站的经验
  • Python语法速览与机器学习开发环境搭建
  • SegmentFault 技术周刊 Vol.27 - Git 学习宝典:程序员走江湖必备
  • Spring Security中异常上抛机制及对于转型处理的一些感悟
  • 每天一个设计模式之命令模式
  • 设计模式(12)迭代器模式(讲解+应用)
  • 通过git安装npm私有模块
  • 温故知新之javascript面向对象
  • LevelDB 入门 —— 全面了解 LevelDB 的功能特性
  • ​secrets --- 生成管理密码的安全随机数​
  • # Python csv、xlsx、json、二进制(MP3) 文件读写基本使用
  • #if 1...#endif
  • (12)目标检测_SSD基于pytorch搭建代码
  • (Redis使用系列) Springboot 实现Redis 同数据源动态切换db 八
  • (ZT)北大教授朱青生给学生的一封信:大学,更是一个科学的保证
  • (二)windows配置JDK环境
  • (二)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (接口自动化)Python3操作MySQL数据库
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第3章 信息系统治理(一)
  • (三)终结任务
  • (十) 初识 Docker file
  • (十三)Java springcloud B2B2C o2o多用户商城 springcloud架构 - SSO单点登录之OAuth2.0 根据token获取用户信息(4)...
  • (万字长文)Spring的核心知识尽揽其中
  • (转)IOS中获取各种文件的目录路径的方法
  • *p=a是把a的值赋给p,p=a是把a的地址赋给p。
  • .net core 6 redis操作类
  • .NET Standard 支持的 .NET Framework 和 .NET Core
  • .one4-V-XXXXXXXX勒索病毒数据怎么处理|数据解密恢复
  • @RequestParam详解
  • [ SNOI 2013 ] Quare
  • [2669]2-2 Time类的定义
  • [⑧ADRV902x]: Digital Pre-Distortion (DPD)学习笔记