zoukankan      html  css  js  c++  java
  • /使用匿名内部类来复写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.    };  



    我试了下,这个是好使的。 
  • 相关阅读:
    监控里的主码流和子码流是什么意思
    监控硬盘容量计算
    一个能让你了解所有函数调用顺序的Android库
    电工选线
    oracle linux dtrace
    list all of the Oracle 12c hidden undocumented parameters
    Oracle Extended Tracing
    window 驱动开发
    win7 x64 dtrace
    How to Use Dtrace Tracing Ruby Executing
  • 原文地址:https://www.cnblogs.com/tfy1332/p/3653588.html
Copyright © 2011-2022 走看看