开发者社区> 问答> 正文

对Handler的理解:报错

点击进入

整个Android Framework都是基于Handler机制来运行的,比如Android app 响应点击事件,启动Activity,更新界面等等,Handler的重要性不言而喻。

Handler 的本质是事件驱动程序设计模型的在Android系统中的具体实现,那事件驱动程序设计模型是什么?

事件驱动模型典型的应用是GUI系统中,在GUI系统中应用程序要在未来不确定的时间里响应用户的UI事件。如果是传统的编程模型,那应用程序必须有个线程去轮询GUI系统以及时发现并处理消息,这是非常浪费cpu资源的。

而事件驱动程序设计模型解决了这个问题,事件驱动程序模型有以下特点。

1、 有一个消息队列,存放消息。

2、 有一个轮询器,不停轮询消息队列,如果没有消息那轮询器就会休眠。

3、 有消息实体,而且每个消息都与一个处理消息的Handler绑定。Handler的生命周期都很短。

这样的话当没有消息的时候cpu就不用在那空转,而有了消息之后再唤醒该线程。这样还有一个好处,就是这个线程不仅可以处理UI的事件,其他的事件同样可以发到该消息队列中。

1、 Runnable 和 Message可以被压入某个MessageQueue中,形成一个集合

2、 Looper循环地去做某件事

比如在这个例子中,它不断地从MessageQueue中取出一个item,然后传给Handler进行处理,如此循环往复。加入队列为空,那么它会进入休眠。

3、 Handler是真正“处理事情”的地方。

它利用自身的处理机制,对传入的各种Object进行相应的处理并产生最终结果。

用一句话来概括它们,就是:

Looper不断获取MessageQueue中的一个Message,然后由Handler来处理。

可以看出,上面的几个对象是缺一不可。它们各司其职,很像一台计算机中CPU的工作方式:中央处理器(Looper)不断地从内存(MessageQueue)中读取指令(Message),执行指令(Handler),最终产生结果。

为什么主线程可以创建Handler对象,而自己创建的线程直接创建Handler就会报


我们先去看一下主线程启动的时候做了什么。


这是从 ActivityThread.java类中截取的main函数的代码,

这里有两行关键代码:

Looper.prepareMainLooper();

Looper.loop();

查一下api文档,找到Looper,如下:




在类的概述中,官方的描述是:Looper的作用是为线程创建消息轮询器。线程默认没有消息轮询器与他关联,如果想关联就要调用Looper.perpare(),然后调用 Looper.loop();然后官方给出了示例代码。

但是我们在源代码中看到的是 Looper.perpareMainLooper();查找文档:



文档中的说明是初始化该线程应用的主线程,还说这个方法由Android 环境为我们调用,我们自己不用调用。

我们看一下该方法的源代码,还是调用了 prepare()方法,只是多了

setMainLooper();和设置该Looper不能退出。

由此我们可以总结出:自己的线程如果也想创建Handler必须调用Looper的prepare与loop两个方法。

1、 Looper的prepare和loop中到底做了什么?

prepare方法只是创建了一个Looper然后关联到当前线程,

loop方法就是去消息队列不停地读取消息,而且如果消息队列中没有消息的时候该线程就会被阻塞,注意 might block。

 点击进入


展开
收起
kun坤 2020-06-08 11:03:22 499 0
1 条回答
写回答
取消 提交回答
  • 项目分享:移动商城_微信小程序
    源代码下载(百度网盘): http://pan.baidu.com/s/1jHQstaI  
    功能包括:商品橱窗,商品搜索,购物车,结账等功能
    这个不错,代码比较规范,很好的学习范例
    微信小程序是基于React Native开发的,体验接近原生APP,发展前景值得重视

    2020-06-08 17:58:51
    赞同 展开评论 打赏
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载