首页 > 其他 > 详细

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

时间:2014-04-09 20:40:00      阅读:707      评论:0      收藏:0      [点我收藏+]
例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楼写的那样就行了!!bubuko.com,布布扣
5 楼 sserf 2011-09-28  
不错,很全面,转了!
4 楼 cj83226 2011-09-05  
Java代码  bubuko.com,布布扣
  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代码  bubuko.com,布布扣
  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代码  bubuko.com,布布扣
  1. if (i == 100){     
  2.                 //将线程对象从队列中移除     
  3.                updateBarHandler.removeCallbacks(updateThread);      
  4.             }     


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

Java代码  bubuko.com,布布扣
  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代码  bubuko.com,布布扣
  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.    };  



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

/使用匿名内部类来复写Handler当中的handlerMessage()方法,布布扣,bubuko.com

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

原文:http://www.cnblogs.com/tfy1332/p/3653588.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!