首页 > 编程知识 正文

简述handler机制,handler的实现

时间:2023-05-06 19:38:24 阅读:201638 作者:4486

一、Handler是什么?

Handler在我们android开发中是一项非常重要的机制,那Handler是什么呢?Handler是android提供用于更新UI的一套机制,也是消息处理机制。

Handler的主要作用有两个:

        (1).在新启动的线程中发送消息

                    (2).在主线程中获取,处理消息。

解释:(1) 当应用程序启动时,Android首先会开启一个主线程 (也就是UI线程) , 主线程为管理界面中的UI控件, 进行事件分发, 比如说, 你要是点击一个 Button ,Android会分发事件到Button上,来响应你的操作。 主线程(UI线程)就是android程序从启动运行到最后的程序。

(2) 如果此时需要一个耗时的操作,例如: 联网读取数据,或者读取本地较大的一个文件的时候,你不能把这些操作放在主线程中,如果你放在主线程中的话,界面会出现假死现象, 如果5秒钟还没有完成的话,会收到Android系统的一个错误提示  "强制关闭"。

(3)这个时候我们需要把这些耗时的操作,放在一个子线程中,因为子线程涉及到UI更新,Android主线程是线程不安全的, 也就是说,更新UI只能在主线程中更新,子线程中操作是危险的。

(4)这个时候,Handler就出现了。,来解决这个复杂的问题 ,由于Handler运行在主线程中(UI线程中),  它与子线程可以通过Message对象来传递数据, 这个时候,Handler就承担着接受子线程传过来的(子线程用sendMessage()方法传弟)Message对象(里面包含数据)  , 把这些消息放入主线程队列中,配合主线程进行更新UI。

二、为什么要用Handler

如果我们不用Handler去发送消息,更新UI可以吗?

答案是不行的。 Android在设计的时候,就封装了一套消息创建,传递,处理机制,如果不遵循这样的机制,就没有办法更新UI信息的,就会抛出异常信息。

抛出异常的描述:不能在非UI线程中去更新UI

三、 Handler怎么用

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

        (1)合理调度安排消息和runnable对象,使它们在将来的某个点被执行.

        (2)安排一个动作在不同的线程中执行

Handler中开启线程和分发消息的一些方法:

      post(Runnable)直接开启Runnable线程

      postAtTime(Runnable,long)在指定的时间long,开始启动线程

      postDelayed(Runnable long)在延迟long时间后,启动Runnable线程

      sendEmptyMessage(int) 发送指定的消息,通过参数int来区分不同的消息

      sendMessage(Message)发送消息到UI线程中

      sendMessageAtTime(Message,long)     这个long代表的是系统时间,不推荐用

     sendMessageDelayed(Message,long)    此方法long代表调用后几秒后执行。

   sendMessage类方法, 允许你安排一个带数据的Message对象到队列中,等待更新.

handler基本使用: 1)在主线程中,使用handler很简单,new一个Handler对象实现其handleMessage方法,在 handleMessage 中提供收到消息后相应的处理方法即可。(接收消息,并且更新UI)

                     2)在新启动的线程中发送消息

示例:

public class HandlerActivity extends AppCompatActivity { private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); tv.setText("msg.arg1:"+msg.arg1+"--msg.arg2:"+msg.arg2); } }; private TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_handler); initView(); new Thread(new Runnable() { @Override public void run() { Message msg = new Message();//实例化消息对象 msg.arg1 = 99;//携带参数 msg.arg2 = 100;//携带参数 Object str = new Object();//实例化对象 msg.obj = str; //携带参数为实体类对象 } }); } private void initView() { tv = (TextView) findViewById(R.id.tv); }} handler运行机制:

 

 

 Handler机制也可叫异步消息机制,它主要由4个部分组成:Message,Handler,MessageQueue,Looper,在上面图中我们已经有了大致印象,接下来我们对4个成员进行着重的了解:

1.Message
  Message是在线程之间传递的消息,它可以在内部携带少量的信息,用于在不同线程之间交换数据。使用Message的arg1和arg2便可携带int数据,使用obj便可携带Object类型数据。

2.Handler
  Handler顾名思义就是处理者的意思,它只要用于在子线程发送消息对象Message,在UI线程处理消息对象Message,在子线程调用sendMessage方法发送消息对象Message,而发送的消息经过一系列地辗转之后最终会被传递到Handler的handleMessage方法中,最终在handleMessage方法中消息对象Message被处理。

3.MessageQueue
  MessageQueue就是消息队列的意思,它只要用于存放所有通过Handler发送过来的消息。这部分消息会一直存放于消息队列当中,等待被处理。每个线程中只会有一个MessageQueue对象,请牢记这句话。其实从字面上就可以看出,MessageQueue底层数据结构是队列,而且这个队列只存放Message对象。

4.Looper
  Looper是每个线程中的MessageQueue的管家,调用Looper的loop()方法后,就会进入到一个无限循环当中,然后每当MesssageQueue中存在一条消息,Looper就会将这条消息取出,并将它传递到Handler的handleMessage()方法中。每个线程只有一个Looper对象。

  了解了上述Handler机制的4个成员后,我们再来把思路理一遍:首先在UI线程我们创建了一个Handler实例对象,无论是匿名内部类还是自定义类生成的Handler实例对象,我们都需要对handleMessage方法进行重写,在handleMessage方法中我们可以通过参数msg来写接受消息过后UIi线程的逻辑处理,接着我们创建子线程,在子线程中需要更新UI的时候,新建一个Message对象,并且将消息的数据记录在这个消息对象Message的内部,比如arg1,arg2,obj等,然后通过前面的Handler实例对象调用sendMessge方法把这个Message实例对象发送出去,之后这个消息会被存放于MessageQueue中等待被处理,此时MessageQueue的管家Looper正在不停的把MessageQueue存在的消息取出来,通过回调dispatchMessage方法将消息传递给Handler的handleMessage方法,最终前面提到的消息会被Looper从MessageQueue中取出来传递给handleMessage方法,最终得到处理。这就是Handler机制整个的工作流程。应该都差不多懂了吧,感觉我写的很接地气啊。

Handler运行源码篇

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。