Android 开发中的消息机制 Looper基础

Looper对象在线程中的应用及常见 RuntimeException 异常处理


一、前言

           在耗时操作时开启新线程,新线程需要开启一个Looper对象,启动一个消息循环。主线程默认会有一个Looper,而开启的新线程没有 Looper 需要创建Looper对象,与当前线程进行绑定。开启消息循环,对子线程的进行消息处理操作。

       当在主线程中要进行某一操作比较耗时时,就需要开启新线程来处理,主线程通常等待时间在 5 秒左右,大于 5 秒的操作会报错,所以需要子线程。


二、子线程中未绑定 Looper 对象引起的异常及处理

     出现异常的代码:(以下代码是本人文件的部分代码,部分类是由于需要个人创建的)

new Thread(new Runnable() {
                    @Override
                    public void run() {
                        GetMessageByIdFromWeb getMById = new GetMessageByIdFromWeb(); //获取对象 ById
                        message = getMById.getMessage(_id);
                        Toast.makeText(context,"该对象的 id:"+message.getId()+","+"content:"+message.getContent(),Toast.LENGTH_SHORT).show();
                    }
                }).start();

       报异常:



     处理后的代码:

new Thread(new Runnable() {
                    @Override
                    public void run() {
                        Looper.prepare();//修改处
                        GetMessageByIdFromWeb getMById = new GetMessageByIdFromWeb(); //获取对象 ById
                        message = getMById.getMessage(_id);
                        Toast.makeText(context,"该对象的 id:"+message.getId()+","+"content:"+message.getContent(),Toast.LENGTH_SHORT).show();
                        Looper.loop();//修改处
                    }
                }).start();

      Looper.prepare();//该语句代表开启一个数据循环

      Looper.loop();//该语句之后的代码不执行

       正确运行,不报异常


三、Looper 的理解

  (1)handler、message、looper、MessageQueue 对象之间的关联

       简单理解:子线程中消息处理handler 与 message 与 looper。handler 有一个消息队列  MessageQueue , handler 处理的消息 Message 对象都来自这个消息队列 MessageQueue  拿出来的 Message,Looper 负责遍历和拿取消息队列内的消息给 handler。每一个线程对应绑定一个 Looper 对象。
  (2)子线程需要新建 Looper对象开启消息循环
       handler 其代理作用,具体对象发送请求,通过 handler,这里主线程通过 handler.sendMessage(Message msg);来发送消息之子线程。 handler 把这个请求存入 messageQueue 队列;Looper 对象是来处理 该队列的,实例化 Looper 对象,开启一个消息循环,的护理子线程与主线程的交互。Looper 中有一个消息循环,循环读取 MessageQueue 队列的消息,当底层有消息请求时,继续存返入该队列,实例化的 Looper 对象循环遍历消息,交给对应的 Handler 处理;每个线程 handler对应一个Looper ,仅绑定一个 looper 对象,开启消息循环。handler 处理对请求进行处理,调用相关方法相应操作,进行界面的修改。
      (3)主线程默认有一个 Looper对象

        Looper 是用来封装消息循环和消息队列 (MessageQueue) 的一个类,用于在 android 多线程、子线程中进行消息处理。主线程默认有一个Looper消息处理对象。handler其实可以看做是一个工具类,用来向消息队列中插入消息的。handler 与当前线程进行绑定,Looper类用来为一个线程开启一个消息循环。 Looper对象通过MessageQueue来存放消息和事件。一个线程只能有一个Looper,对应一个MessageQueue。


四、looper 要点

      1. Looper类用来为一个线程开启一个消息循环。 


      2. 通常是通过Handler对象来与Looper进行交互的。Handler用来向指定的Looper发送消息及定义处理方法。 
 默认情况下Handler会与其被定义时所在线程的Looper绑定。在主线程中通过handler.sendmessage发送消息


       3. 在非主线程中直接new Handler() 会报如下的错误: 
AndroidRuntime Uncaught handler: thread Thread-8 exiting due to uncaught exception 
AndroidRuntime java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 


原因是非主线程中默认没有创建Looper对象,需要先调用Looper.prepare()启用Looper。 

      4. Looper.loop(); 让Looper开始工作,从消息队列里取消息,处理消息。 

    注意:写在Looper.loop()之后的代码不会被执行,这个函数内部应该是一个循环,当调用mHandler.getLooper().quit()后,loop才会中止,其后的代码才能得以运行。 

      5. 基于以上知识,可实现主线程给子线程(非主线程)发送消息。


五、关系图








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

niaonao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值