handler 讲解

 

Handler 的定义

 

  *  主要接受子线程发送的数据,并用此数据配合更新主线程更新UI, 当应用 程序 启动时,Android首先会开启一个 主线程  (也就是UI线程)

      主线程管理界面 中的UI控件 ,并进行事件分发。 比如说, 你要是点击一个 Button ,Android会分发事件到Button上,来响应你的操作。如果

      此时需要一个耗时的操作,例如: 联网读取数据, 或者读取本地较大的一个文件 的时候,你不能把这些操作放在主线程中。如果你把耗时

      操作放在主线程中的话,界面会出现假死现象,如果5秒钟还没有完成的话,会收到Android系统 的一个错误提示   "强制关闭"。

 

  *  为了解决这个问题,我们需要把这些耗时的操作,放在一个子线程中。因为子线程中涉及到UI更新,所以Android主线程是线程不安全的。

      也就是说, 更新UI只能在主线程中更新, 子线程中操作是危险的。   这个时候,Handler就出现了,用来解决 这个复杂的问题 ,由于

      Handler运行 在主线程(UI线程中), 它与子线程可以通过Message对象来传递数据, Handler就承担着接受子线程传过来的(子线程用

      sendMessage()方法传递)Message对象(里面包含数据),把这些消息放入主线程队列中,配合主线程进行更新UI。

 

Handler的特点

   *    handler可以分发Message对象和Runnable对象到主线程中, 每个Handler实例 ,都会绑定到创建他的线程中(一般是位于主线程)。

 

   *    两个作用(1):   安排Message或Runnable 在某个主线程中某个地方执行,(2)安排一个动作在不同的线程中执行。

 

Handler类中分发消息常用方法

 

   *   post(Runnable)

   *   postAtTime(Runnable,  long)

   *   postDelayed(Runnable, long)

   *   sendEmptyMessage(int)

   *   sendMessage(Message)

   *   sendMessageAtTime(Message, long)

   *   sendMessageDelayed(Message, long)

       以上post相关的方法允许你传递一个Runnable对象到主线程队列中,sendMessage相关方法允许传递一个带数据的Message对象到队列

       中等待主线程接受,并执行相应功能。

 

Handler 举例

 

       例1: 利用Handler 作耗时操作(类似定时器)

 

      通过AlertDialog.Builder类的setItems方法创建列表对话框。列表对话框关闭后,会显示一个无按钮的提示对话框,若不进行任何操作,

      该对话框不会自动关闭。我们通过Handler提供的方法可以实现10秒钟后自动关闭对话框。

 

 

               private void showListDialog(){

 

                    new AlertDialog.Builder(this).setTitle("选择城市”) .setItems(citys,

 

                          new  DialogInterface.OnClickListener(){

 

                                public void  OnClick(DialogInterface dialog, int which){

                                  final AlertDialog ad = new AlertDialog.Builder(MainActivity.this) .setMessage(

                                     "您已经选择了:" + which + ": " +citys[which]).show;

                                   // 一个Handler对应一个消息队列。

                                   android.os.Handler handler = new andorid.os.Handler();

                                   //这个方法的作用是:将要执行的线程对象放入到队列当中,待时间结束后,运行制定的线程对象

                                   //第二个参数是long类型:延迟的时间,以毫秒为单位

                                   //Runnable对象中run方法的执行和主线程的执行是异步的。

这里所说的异步, 就是说postDelayed()方法执行就返回,和Runnable中的方法是异步执行的。

                                   //就是说发送消息和接收消息不是同步的处理。

                                   handler.postDelayed(new Runnable ()

                                       {

                                          @Override

                                            public void run{

 

                                                      ad.dismiss();s

                                                                     }

                                       }, 10*1000 );

 

 

 

                  }}) .show();

 

 

                  }

 

 

 

 

 消息机制细谈 (message handler looper messagethread)

 在handler的简单用法中,我们自己简单new出一个handler 然后调用它的sendMessage方法发出一条消息。然后在handler类重写了handler的handlerMessage方法来进行处理。看似就是这么简单的俩步,其实背后隐藏了很多我们不知道的流程。
   在介绍这个之前,我先介绍几个概念
  1。Message 这个应该很清楚吧 就是我们发送的消息 介绍一个里面的一个方法Message.obtain函数。作用是从Message Pool中取出一个Message,如果Message Pool中已经没有Message可取则新建一个Message返回,同时用对应的参数给得到的Message对象赋值。 message Pool 我的理解就是一个缓存区。就是把用过的Message放进这里面为了以后用而已。要不每次都要new一个message起步麻烦。这个应该跟String pool的原理一样。姑且我们把它视为同一个作用的东西。
2.MessageQueue
顾名思义就是消息队列,干什么用的 当然是存放消息用的
3。Looper
我暂且叫他循环体吧。 主要就是从MessageQueue中读取消息。
4.handler 当然就是处理发来的消息了
下面我就把这个四个联系起来,看看他们在内部到底怎么执行。
首先通过handler发出一条消息,发到哪呢 肯定是MessageQueue里,最终会调用MessageQueue的 enqueueMessage函数,enqueueMessage根据上面的接收的Message的队列的构造把接收到的Message放入队列中。 MessageQueue的removeMessages函数根据上面的接收的Message的队列的构造把接收到的Message从队列中删除,并且调用对应Message对象的recycle函数把不用的Message放入Message Pool中。通过Loop从MessageQueue中从前往后取出Message,然后通过Handler的dispatchMessage函数进行消息的处理(可见消息的处理是Handler负责的),消息处理完了以后通过Message对象的recycle函数放到Message Pool中,以便下次使用,通过Pool的处理提供了一定的内存管理从而加速消息对象的获取。至于如何处理就看你的handler如何定义了由你指定(三个方法,优先级从高到低:Message里面的Callback,一个实现了Runnable接口的对象,其中run函数做处理工作;Handler里面的mCallback指向的一个实现了 Callback接口的对象,里面的handleMessage进行处理;处理消息Handler对象对应的类继承并实现了其中 handleMessage函数,通过这个实现的handleMessage函数处理消息)。
  大致流程就是handler------->>发送message---->>MessageQueue
Looper--->取出message从messagequeue中----->>在触发handler的消息分发函数----调用handler中定义的方法.
这里有个疑问那looper 和messagequeue什么时候生成呢。其实messagequeue在Looper创建的时候就生成了。那Looper什么时候生成呢?其实 Looper是跟一个线程关联的。而主线程会自动调用prepareMainLooper生成自己的Looper,但其他线程则不会自己创建了。待会再说。
  先来看看我们上次的简单handler例子。这下应该知道他们内部的流程了吧。其实我们在Hander handler=new Handler();其实就已经把主线程的Looper关联上来了,有了Looper我们也就有了MessageQueue 所以我们在调用sendMessage的时候就把这个Message发送到由Looper创建的MessageQueue里。Looper有主线程创建的,当然消息会在主线程处理了。这样就实现了简单的子线程到主线程的通信了。
那好,如果现在我要创建子线程的Looper呢 然后怎么把这个Looper绑定Handler上呢。其实很简单 在子线程调用Looper.prepare()就可以创建子线程的Looper 然后通过Looper.myLooper()就可以拿到这个Looper对象,最后就是把这个Looper 跟Handler绑定起来。其实在构建handler对象的时候我们除了我默认无参构造方法(这个就是我们上次那个例子用的)还有有参的构造方法,就是传 Looper的。好了,这样就可以把Looper跟Handler绑定起来了。这你在主线程调用Handler.sendMessage就是把 message发到子线程里来了。这样就实现主线程到子线程的通信了。以此类推各种样式的通信都是可以的。

 

参考:http://www.eoeandroid.com/thread-35202-1-1.html

 

 

 

     
 有用的网址:http://byandby.javaeye.com/blog/832467(andorid Handler 的使用一)

                         http://byandby.javaeye.com/blog/832915(andorid Handler 的使用二)

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring框架是一个开源的Java应用程序框架,用于构建企业级应用程序。它提供了一种轻量级的、非侵入式的方式来管理Java对象的生命周期和依赖关系,从而简化了应用程序的开发和维护过程。下面是对Spring框架源码的简要讲解: 1. 核心容器(Core Container):Spring框架的核心是其IoC容器(Inversion of Control)。它通过IoC容器来管理和组织应用程序中的Bean对象。在IoC容器中,Spring使用`BeanFactory`接口和其实现类`DefaultListableBeanFactory`来加载、配置和管理Bean对象。 2. 上下文(Context):Spring还提供了更高级的上下文功能,如`ApplicationContext`接口和其实现类`AnnotationConfigApplicationContext`、`XmlWebApplicationContext`等。上下文扩展了`BeanFactory`的功能,提供了更多的企业级特性,如国际化、事件传播、资源加载等。 3. AOP(Aspect-Oriented Programming):Spring框架实现了AOP的支持,用于将横切关注点(cross-cutting concerns)从核心业务逻辑中分离出来。Spring AOP基于代理模式和动态代理技术,通过面向切面编程来实现横切关注点的模块化。 4. 数据访问(Data Access):Spring框架提供了对各种数据访问技术的支持,包括JDBC、ORM(如Hibernate、MyBatis)和事务管理。它通过抽象出数据访问层的公共接口,使得应用程序可以更容易地切换和集成不同的数据访问技术。 5. Web支持:Spring框架还提供了对Web应用程序开发的支持,包括Web MVC、RESTful服务、WebSocket等。它通过`DispatcherServlet`和一系列的处理器(Handler)来处理Web请求,并提供了一套强大的机制来实现灵活的Web应用程序开发。 6. 测试支持:Spring框架还提供了对单元测试和集成测试的支持,如`JUnit`和`TestNG`的集成、模拟对象(Mock Objects)的支持等。这使得开发人员可以更方便地编写和执行各种测试用例。 需要注意的是,Spring框架是一个非常庞大而复杂的项目,其源代码具有很高的复杂性和技术难度。如果您有兴趣深入了解Spring框架的源码,建议您从官方网站下载源代码并阅读相关文档,或者参考一些专门讲解Spring源码的书籍和教程。同时,熟悉Java编程、设计模式和IoC、AOP等基本概念也是理解和阅读Spring源码的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值