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.    };  



    我试了下,这个是好使的。 
  • 相关阅读:
    定力
    cordova build android 环境的坑
    我和数据差个“axios" -- axios的原理解析
    Promise的原理探究及手写Promise
    vue长列表优化
    koa-中间件使用
    vue组件库自动生成文档-vue-styleguidist(二)
    vue组件库自动生成文档-vue-styleguidist(一)
    vue组件库自动生成文档-生成方式对比(1)
    我的目录
  • 原文地址:https://www.cnblogs.com/tfy1332/p/3653588.html
Copyright © 2011-2022 走看看