报错“Can't create handler inside thread that has not called Looper.prepare()” 的处理方法

时间:2021-05-04 20:45:06

个人网站:极客时代    

如果在编译的时候出现这样的报错:Can't create handler inside thread that has not called Looper.prepare(),是因为新new的线程中出错,线程中没有消息处理机制,无法进行消息处理。

    解决方法:在线程中报错的地方,在报错方法的前面加上Looper.prepare();在后面加上Looper.loop();之后再编译运行就不会报错了。例如下面的例子

<pre name="code" class="java">new Thread() { // 网络相关处理不能在主线程上进行
                        @Override
                        public void run() {
                            Log.e("debug3","here");
             。。。。。。。。。。。。。
                            Log.e("debug4","here");
                                Looper.prepare();
                                new AlertDialog.Builder(getActivity()).setTitle("提示")//设置对话框标题
                                        .setMessage("用户名已经被使用!")//设置显示的内容
                                        .setPositiveButton("确定", null).setNegativeButton("返回", null).show();//在按键响应事件中显示此对话框
                                Looper.loop();
           }
}

    Android编程中,会有一个主线程,一般的操作或者处理事件在主线程中就可以实现,但是在涉及比较耗时的操作时,需要新new一个子线程,把这些操作放入新的线程中,而不是在主线程里。

    //子线程不能直接更新UI,最终还得转变为主线程处理,利用Handler机制。如果想直接更新,就会报错。

    Looper类用来管理特定线程内对象之间的消息交换,Looper.prepare()用来创建消息循环,Looper.loop()开始消息循环。一个线程只有一个Looper,并且Looper对象是通过消息队列(Message Queue)来存放消息以及事件。只有建立了Looper对象,才能创建handler,利用Looper.loop()获取message对象。主线程中是建立了Looper的,无需我们自己去添加,但是在自己new的线程中,我们需要自己指定Looper对象。

    //要注意线程的执行顺序:

{ //主线程

......................
      new Thread() { // 网络相关处理不能在主线程上进行
                        @Override
                        public void run() {
                            Log.e("debug2","here");
...........................
                        }
     } 
............
   Log.e("debug1", "here");
...............
}   

会先输出debug1,后输出debug2.所以不要将需要在debug2执行后才希望执行的代码放到debug1的位置。