我是靠谱客的博主 满意红牛,最近开发中收集的这篇文章主要介绍Android 开发中的消息机制 Looper基础Looper对象在线程中的应用及常见 RuntimeException 异常处理,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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. 基于以上知识,可实现主线程给子线程(非主线程)发送消息。


五、关系图








最后

以上就是满意红牛为你收集整理的Android 开发中的消息机制 Looper基础Looper对象在线程中的应用及常见 RuntimeException 异常处理的全部内容,希望文章能够帮你解决Android 开发中的消息机制 Looper基础Looper对象在线程中的应用及常见 RuntimeException 异常处理所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(63)

评论列表共有 0 条评论

立即
投稿
返回
顶部