• 【转】在子线程中new Handler报错--Can't create handler inside thread that has not called Looper.prepare()


    在子线程中new一个Handler为什么会报以下错误?

    java.lang.RuntimeException: 

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

    这是因为Handler对象与其调用者在同一线程中,如果在Handler中设置了延时操作,则调用线程也会堵塞。每个Handler对象都会绑定一个Looper对象,每个Looper对象对应一个消息队列(MessageQueue)。如果在创建Handler时不指定与其绑定的Looper对象,系统默认会将当前线程的Looper绑定到该Handler上。
    在主线程中,可以直接使用new Handler()创建Handler对象,其将自动与主线程的Looper对象绑定;在非主线程中直接这样创建Handler则会报错,因为Android系统默认情况下非主线程中没有开启Looper,而Handler对象必须绑定Looper对象。这种情况下,则有两种方法可以解决此问题:

    方法1:需先在该线程中手动开启Looper(Looper.prepare()-->Looper.loop()),然后将其绑定到Handler对象上;

    final Runnable runnable = new Runnable() {
      @Override
      public void run() {
        //执行耗时操作
        try {
    
          Log.e("bm", "runnable线程: " + Thread.currentThread().getId()+ " name:" + Thread.currentThread().getName());
    
          Thread.sleep(2000);
          Log.e("bm", "执行完耗时操作了~");
        } catch (InterruptedException e) {
        e.printStackTrace();
        }
      }
    };
    new Thread() {
      public void run() {
        Looper.prepare();
        new Handler().post(runnable);//在子线程中直接去new 一个handler
        Looper.loop();    //这种情况下,Runnable对象是运行在子线程中的,可以进行联网操作,但是不能更新UI
      }
    }.start();
    

      

    方法2:通过Looper.getMainLooper(),获得主线程的Looper,将其绑定到此Handler对象上。

    final Runnable runnable = new Runnable() {
      @Override
      public void run() {
        //执行耗时操作
        try {
    
          Log.e("bm", "runnable线程: " + Thread.currentThread().getId()+ " name:" + Thread.currentThread().getName());
          Thread.sleep(2000);
          Log.e("bm", "执行完耗时操作了~");
        } catch (InterruptedException e) {
        e.printStackTrace();
        }
      }
    };
    new Thread() {
      public void run() {
        new Handler(Looper.getMainLooper()).post(runnable);//在子线程中直接去new 一个handler
    
        //这种情况下,Runnable对象是运行在主线程中的,不可以进行联网操作,但是可以更新UI
      }
    }.start();
    

      

    from:https://www.cnblogs.com/jingmo0319/p/5730963.html

  • 相关阅读:
    C#使用表达式树实现对象复制
    用vbs将字符串复制到剪贴板
    C# 动态获取程序集信息
    关于ftp的主动模式(Active Mode)和被动模式(Passive Mode)
    %userprofile%\Local Settings文件夹拒绝访问怎么办
    在Winform框架的多文档界面中实现双击子窗口单独弹出或拖出及拽回的处理
    ABP VNext框架基础知识介绍(1)框架基础类继承关系
    ABP开发框架中分页查询排序的实现处理
    Vue&Element开发框架中增加工作流处理,工作流的各个管理页面的界面处理
    基于ABP开发框架的技术点分析和项目快速开发实现
  • 原文地址:https://www.cnblogs.com/xuan52rock/p/10124189.html
Copyright © 2020-2023  润新知