在子线程中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();

在子线程中new Handler报错--Can't create handler inside thread that has not called Looper.prepare()的更多相关文章

  1. 【转】在子线程中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 ...

  2. 转 在子线程中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 ...

  3. 关于子线程使用Toast报错Can't create handler inside thread that has not called Looper.prepare()的解决办法

    形同如下代码,在Thread中调用Toast显示错误信息: new Thread(new Runnable(){ @Override public void run() { try{ weatherD ...

  4. Android 线程更新UI报错 : Can't create handler inside thread that has not called Looper.prepare()

    MainActivity中有一个按钮,绑定了save方法 public void save(View view) { String title = titleText.getText().toStri ...

  5. Android进阶(十六)子线程调用Toast报Can't create handler inside thread that has not called Looper.prepare() 错误

    原子线程调用Toast报Can't create handler inside thread that has not called Looper.prepare() 错误 今天用子线程调Toast报 ...

  6. Mysql in子查询中加limit报错

    Mysql in子查询中加limit报错 select id from aa where id in ( select id from bb limit 10 ); 改写成 SELECT id FRO ...

  7. Android handler 报错处理Can't create handler inside thread that has not called Looper.prepare()

    问题: 写了一个sdk给其他人用,提供一个回调函数,函数使用了handler处理消息 // handler监听网络请求,完成后操作回调函数 final Handler trigerGfHandler ...

  8. OkHttp下载文件中途断网报Can't create handler inside thread that has not called Looper.prepare()异常的解决办法

    最近做项目时出现个问题. 在一个基类中,创建一个Handler对象用于主线程向子线程发送数据,代码如下: this.mThirdHandler = new Handler(){ @Override p ...

  9. Android进阶(八)Can't create handler inside thread that has not called Looper.prepare()

    Error:Can't create handler inside thread that has not called Looper.prepare() 原代码: //利用Handler消息传递机制 ...

随机推荐

  1. Java基础(二) ---- 继承(Inheritance)

  2. VI 命令 gg 跳到第一行,dG 删除后面的所有内容

    VI 命令 gg 跳到第一行,dG 删除后面的所有内容

  3. SQLServer查询所有库表结构信息

    1.查询数据库中的所有数据库名: SELECT Name FROM Master..SysDatabases ORDER BY Name 2.查询某个数据库中所有的表名: SELECT Name FR ...

  4. jsp+tomcat+mysql+sevlet+javabean配置过程

    在配置jsp开发环境的过程中会碰到不少问题,感谢网上的许多前辈的经验总结,作者cl41的JSP连接Mysql数据库攻略和作者Saulzy的MySQL学习笔记等文章对我来说简直是雪中送碳,为了帮助象我一 ...

  5. SpringBoot Demo

    Spring Boot,微框架,确实不错,很方便. 相关网站链接: http://www.tuicool.com/articles/veUjQba https://www.gitbook.com/bo ...

  6. 学习一下mef

    微软 http://msdn.microsoft.com/zh-cn/magazine/ee291628.aspx mef http://biancheng.dnbcw.info/net/370552 ...

  7. 在angular中实现下拉框的两种方式 ng-repeat和 ng-option

    1. ng-repeat实现下拉框: select下拉框里option组装成下拉框,这里利用ng-repeat指令来创建 实现源码   <!DOCTYPE html> <html&g ...

  8. 用jquery解析JSON数据的方法以及字符串转换成json的3种方法

    用jquery解析JSON数据的方法,作为jquery异步请求的传输对象,jquery请求后返回的结果是 json对象,这里考虑的都是服务器返回JSON形式的字符串的形式,对于利用JSONObject ...

  9. High Memory in the Linux Kernel

    This is enabled via the PAE (Physical Address Extension) extension of the PentiumPro processors. PAE ...

  10. 转载:reactor模式学习

    最近又重新看了下netty背后的设计思想,接触到了reactor模型.发现以前虽然也看过reactor和proactor模型的介绍,但是真的是只了解了个皮毛. 再重新学习了一遍,有了更深刻的认识.但是 ...