andriod Handler机制原理

      andriod编程有一个麻烦事,便是主线程有太多限制,比如不能执行网络操作,绝大部分控制只能通过它自己更新,为什么?

     开始之前不得不说说程序的工作原理,一个程序往往只启动一个进程,使用window操作系统的人大多有一种经验,程序运行到半路卡死了,失去响应。不管你怎么点它它都不理你,怎么办?耐心好的等,耐心不好的就只有ctrl+alt +del调出进程管理器,然后选中程序所在的进程,直接将它咔嚓了。

     android手机程序也是启动一个进程,对于程序员来说,可以将application看做这个进程的维护者。然后是程序,如果一个进程不启动线程,进程会被怎样执行?当然是根据代码书写顺序一步步走下去。然而很多时候程序的执行还需要依赖外部输入,绝大部分程序都有一个窗口,它们提供一个交互手段,让用户进行操作,不论是敲键盘点鼠标还是摸屏幕,程序都会实时的接受用户的操作产生的数据,然后进行处理。那么这种可以实时反应用户操作的机制是怎么实现的?

      这里涉及到很多的软件硬件的相关知识,比如中断之类的东西,不过普通程序员根本不会去接触也不想去接触那些东西。在andriod里我们只要调用监听重新里面的监听方法就能够实现对用户操作的反应。可是如果要理解andriod的消息处理和handler机制,就不得不了解什么是消息,而消息又是怎么被主线程处理的。

       而android手机里用户的操作也是一种消息,当你触摸屏幕的时候,android系统就会发送消息到当前用户进程,而android系统便在这时开始处理这些消息。

      想象一下这样的场景,一个用户不停的操作一个屏幕,然后你在后面写了一段长长的代码,我要干这我还要干那,程序应该怎么处理?当你有一大堆事情不得不处理的时候怎么办?几种选择,1:一件件来。2:捡紧要的处理,其它的押后。3:什么事情来了就处理什么事,以前的事就不管了。也许还有其它处理方式,这些处理其实都有道理,而且在很多程序里这三种方式都有所体现。比如打印机,一般是按照顺序一个个执行。用程序来实现的话就是一个队列储存所有的请求,然后一个个按先后处理。android手机内部也维护一个这样的消息队列,它一个个按顺序处理消息请求。第2种,绝大部分操作系统都有一个进程优先级的概念,系统通过优先级来确定程序执行的顺序和分配的资源。这个算法和数据结构要稍微复杂,实现起来并不简单。而第三种在游戏里经常见到,点击一个人物修改他的行进方向,这种处理方式让操作的实时性更强。

    android的消息机制是第一种,因为第二种结构复杂,结构复杂意味着开销大,编程也更加困难。而第三种虽然实时性更强但会丢失数据。但第一种有一个大问题。便是一件事处理过长,那么其它事件就会被这个事件堵住,就像挤地铁,一个队伍如果最前面的人磨磨蹭蹭,后面的人就会被堵住。最后车都走了,人还没上。所以在andriod的主线程里任何事件都不能操作时间太长,太长后面的事件就会被堵住。如果在一个按钮监听方法里面写一个死循环,一旦点击,要么整个程序失去响应,要么崩了。

    可是总有一些事情是要耗时的,io操作,复杂运算,怎么办?多线程和消息轮询。多线程可以利用java直接启动,也可以添加service组件。耗时操作被分配出去,主线程只负责两件事,一件,等待用户触发事件,第二件,受到消息,处理消息,显示出来。绝大部分时候它都是闲的,也只有绝大部分时候闲着,主线程才能够在第一时间反应用户的各种触屏事件。既然它把所有事情都分到的其它工作线程处理,那么它怎么知道处理结果?handler机制便出来了。

   handler负责线程中的通信。一个线程是一个有序的操作序列。是不能同时干两件事的,handler机制其实也是这样,它本身就独占了一个线程所有运行时间。和它对应的looper本身就独占了线程的所有资源。这个队列平常的时候是阻塞的,线程被挂起,只有当消息来临时被唤醒,当所有消息处理完毕后挂起。而这些消息携带着外部参数和操作方法的句柄。主线程解析着这个消息。每次消息来临的时候,自动调用对应的handlemessage方法。而handlermessage方法可以对由主线程独自维护和管理的界面组件进行更新操作。

        (因为只有主线程一个人可以操作这些界面资源,也就不需要为这些界面资源设置同步,而java的同步还是异常耗费系统资源的。这样的设计可以有效的提高界面显示的效率,毕竟java本身的二次编译性质让让软件和系统硬件隔了一层,自然效率就没有这么高。不过带来的却是软件开发的便捷和超强移植能力。andriod手机有超多品牌,而苹果公司只有一家。)

         handler使用方法:1绑定looper 因为巨大部分时候都是工作线程提供给主线程参数。所以handler机制默认绑定主线程。直接在你的主线程(又称UI线程中new一个出来便是)  重新消息处理方法。handler本身可以携带方法,message也可以携带方法,这些方法处理优先级比较高,不过一般情况下都是在声明的时候重写handlermessage方法。方法里面的代码执行在主线程。2.将次对象的引用传递给工作线程,然后利用此handler对象发送消息,消息传递回它绑定的looper线程中被处理。

       而作为一个完整的消息轮询机制它也可以被移植到其它工作线程,只是在工作线程中记得,当消息机制运行后,线程便进入阻塞态,只有消息到来才会唤醒次线程,然后消息被先来后到的方式依次处理。这样的应用可以放在一些无需界面的依赖实时参数耗时较长的工作线程中。比如io操作,网络操作等等。

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值