错误解决 Can't create handler inside thread that has not called Looper.prepare()

作为菜鸡,一遇到这种BUG就一脸懵逼,最后还是疯狂的查询百度,得到了这样的解决方法,记录一下,自己测试是可行的。


首先一开始报错的代码是这样的:

 @Override
    public void onClick(View v) {
        if (0 != musicProgressBar.getProgress()) {
            // TODO Auto-generated method stub

            startService();//自己写了个方法包装了开启服务+Toast
        
           //倒计时
            new Timer().schedule(new TimerTask() {
    			
    				@Override
    				public void run() {
    					   	   					
    					if(time > 0){
                                                //在这里musicProgressBar是一个圆形的拖动条,setProgress是设置拖动条当前的值
    						musicProgressBar.setProgress(--time);
    	
    						if(0 == time){
 						    //问题就出在这句Toast里   				            		
 						    Toast.makeText(this, "时间到", Toast.LENGTH_SHORT).show();     										            cancel(); 
    						}
    						
    						
    					}
    					
    				
    			}
    		}, 60*1000, 60*1000);

            
        }else{
            Toast.makeText(this, "您还没有选择时间", Toast.LENGTH_SHORT).show();
        }
    }



在上面的代码中,我在Timer()中开启了一个时间任务,然后重写了run()方法,在里面加入了一句Toast,报错

Can't create handler inside thread that has not called Looper.prepare()

我一开始也以为和Looper.prepare()这个方法有关,查了百度之后发现,Android好像不能再线程中更新UI,这句话我也不是很懂,然后需要把更新UI的这个过程放到主线程里,所以需要用到Handler这个东西,大概意思就是可以在其他线程(类似于Thread和Timer)中使用Handler 和Message。在需要更新UI(目前只知道Toast)的地方,使用Handler将一个Message发送出去,在主线程中接收这个Message,接收到之后就使用Toast或者其他更新UI的事情,大致原理就是这样。


以下是更改之后的代码

MainActivity中,设置Message的接受,以及Toast事件

private Handler mHandler;
mHandler=new Handler(){
        	public void handleMessage(Message msg) {    
                switch (msg.what) {    
                case ID_USER:    
                    //获取传递的数据  
                    Bundle data = msg.getData();  
                    String text = data.getString("str");
                    //处理UI更新等操作  
                    Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
                    stopService();
                }    
            };    
        };


接下来是在run方法中创建一个Message发送出去

@Override
    public void onClick(View v) {
        if (0 != musicProgressBar.getProgress()) {
            // TODO Auto-generated method stub

            startService();
            //执行数据操作,不涉及到UI  

            

            //倒计时
            new Timer().schedule(new TimerTask() {
    			
    				@Override
    				public void run() {
    					
    					/**
    					 * 用一个Handler来处理Toast
    					 */
    					
    					 Message msg = new Message(); //创建一个Message      
			                 msg.what = ID_USER;          //给这个Message一个标识
			                 Bundle data = new Bundle();  //创建一个数据包
    				
    					
    					if(time > 0){
					       //在这里musicProgressBar是一个圆形拖动条,setProgress()是设定当前拖动位置
    						musicProgressBar.setProgress(--time);
    	
    						if(0 == time){
							//把这个数据包添加一个Key为str,后面这一段是我想要Toast的话
    							data.putString("str", "Times up! you can take a break!");
							//添加这段数据包到Message里
    							msg.setData(data);
							//使用Handler将Message发送出去
    							mHandler.sendMessage(msg);       												
        					    
        					    cancel(); 
    						}
    						
    						
    					}
    					
    				
    			}
    		}, 60*1000, 60*1000);

            
        }else{
            Toast.makeText(this, "您还没有选择时间", Toast.LENGTH_SHORT).show();
        }
    }


最后这个错误就解决了,而且Toast也能显示出来。本人菜鸡一个,有错误可以指出来,谢谢




Android开发中,当在一个非UI线程中尝试创建一个Handler对象时,可能会出现"Can't create handler inside thread that has not called Looper.prepare()"的异常。这是因为Handler需要与Looper配合使用来处理消息队列,而非UI线程默认没有与之关联的Looper。 为了解决这个问题,你可以在非UI线程中调用Looper.prepare()方法来创建一个与当前线程关联的Looper对象。然后,在创建Handler之前,调用Looper.loop()方法来启动消息循环。这样就可以在非UI线程中创建Handler对象了。 以下是一个示例代码,演示了如何在Android开发中解决"Can't create handler inside thread that has not called Looper.prepare()"异常: ```java import android.os.Handler; import android.os.Looper; public class MyThread extends Thread { private Handler mHandler; @Override public void run() { // 在非UI线程中调用Looper.prepare()方法创建Looper对象 Looper.prepare(); // 创建Handler对象 mHandler = new Handler(); // 在非UI线程中调用Looper.loop()方法启动消息循环 Looper.loop(); } public Handler getHandler() { return mHandler; } } // 在主线程中使用MyThread来创建Handler对象 MyThread myThread = new MyThread(); myThread.start(); // 获取在非UI线程中创建的Handler对象 Handler handler = myThread.getHandler(); ``` 通过以上代码,你可以在非UI线程中创建一个Handler对象,并在主线程中获取到该Handler对象,从而实现在非UI线程中处理UI相关的操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值