android 多线程 队列,Android 中的线程机制之 Handler

题外话:一直以来学习的时候,都没有写笔记的习惯,前些日子随手写了之后,发现对一些东西理解的更深刻~ 这里就开始写小笔记吧,如果哪里错了,请各位帮忙指正,谢谢

android是单线程模型,所以在多线程的时候,并不能像java一样直接使用new Thread().start();

一.android 线程机制中Handler系列需要理解5个概念:

1.Message: 消息对象,Message Queue中的存放的对象。一个Message Queue中包含多个Message。

Message实例对象通常使用Message类里的静态方法obtain()---该方法有多个重载版本可供选择---通过该方法的创建并不一定是直接创建一个新的实例,而是先从Message Pool(消息池)中看有没有可用的Message实例,存在则直接取出返回这个实例。如果Message Pool中没有可用的Message实例,则才用给定的参数创建一个Message对象。

而调用removeMessages()时,将Message从Message Queue中删除,同时放入到Message Pool中。也可以通过Handler对象的obtainMessage()获取一个Message实例。

在Activity的onStop()或者onDestroy()使用Handler的方法removeMessages(int what) 配合removeCallbacks(Runnable r)或直接使用mHandler.removeCallbacksAndMessages(null);可以避免内存泄露

2.Handler:它直接继承自Object,一个Handler允许发送和处理Message或者Runnable对象,并且会关联到主线程的 MessageQueue 中。每个Handler具有一个单独的线程,并且关联到一个消息队列的线程,就是说一个Handler有一个固有的消息队列。当实例化一个Handler 的时候,它就承载在一个线程和消息队列的线程,这个Handler可以把Message或Runnable压入到消息队列,并且从消息队列中取出 Message或Runnable,进而操作它们。

Handler主要有两个作用:

- 在工作线程中发送消息。

- 在UI线程中获取、处理消息。

上面介绍到Handler可以把一个Message对象或者Runnable对象压入到消息队列中,进而在UI线程中获取Message或者执行Runnable对象,所以Handler把压入消息队列有两大体系,Post和sendMessage:

- Post:Post允许把一个Runnable对象入队到消息队列中。它的方法有:post(Runnable)、postAtTime(Runnable,long)、postDelayed(Runnable,long)。

- sendMessage:sendMessage允许把一个包含消息数据的Message对象压入到消息队列中。它的方法 有:sendEmptyMessage(int)、sendMessage(Message)、 sendMessageAtTime(Message,long)、sendMessageDelayed(Message,long)。

从上面的各种方法可以看出,不管是post还是sendMessage都具有多种方法,它们可以设定Runnable对象和Message对象被入队到消息队列中,是立即执行还是延迟执行。

3.MessageQueue:是一种数据结构,见名知义,就是一个消息队列,存放消息的地方。每一个线程最多只可以拥有一个MessageQueue数据结构。

创建一个线程的时候,并不会自动创建其MessageQueue。通常使用一个Looper对象对该线程的MessageQueue进行管理。主线程创建时,会创建一

个默认的Looper对象,而Looper对象的创建,将自动创建一个Message Queue。其他非主线程,不会自动创建Looper,要需要的时候,通过调

用prepare函数来实现。

4.Looper:是MessageQueue的管理者。每一个MessageQueue都不能脱离Looper而存在,Looper对象的创建是通过prepare函数来实现的。同时每一个Looper对象

和一个线程关联。通过调用Looper.myLooper()可以获得当前线程的Looper对象

创建一个Looper对象时,会同时创建一个MessageQueue对象。除了主线程有默认的Looper,其他线程默认是没有MessageQueue对象的,所以,不能

接受Message。如需要接受,自己定义一个Looper对象(通过prepare函数),这样该线程就有了自己的Looper对象和MessageQueue数据结构了。

Looper从MessageQueue中取出Message然后,交由Handler的handleMessage进行处理。处理完成后,调用Message.recycle()将其放入Message Pool中。

5.HandlerThread:这个类继承Thread类, 在类内部创建了Looper 变量,整体上实现的是通过Looper达到分发消息的作用。

Activity、Looper、Handler的关系如下图所示:

0_129532670095zs.gif.jpeg

Android系统的消息队列和消息循环都是针对具体线程的,一个线程可以存在(当然也可以不存在)一个消息队列和一个消息循环(Looper),特定线程的消息只能分发给本线程,不能进行跨线程,跨进程通讯。但是创建的工作线程默认是没有消息循环和消息队列的,如果想让该线程具有消息队列和消息循环,需要在线程中首先调用Looper.prepare()来创建消息队列,然后调用Looper.loop()进入消息循环。

二. 示例Handler的用法使用Handler对象的sendEmptyMessage或sendMessage方法来传递一个Bundle对象到Handler处理器。对于Handler类提供了重写方法handleMessage(Message msg) 来判断,通过msg.what来区分每条信息。12345678910Handler myHandler =newHandler() {public void handleMessage(Message msg) {switch(msg.what) {caseTestHandler.GUIUPDATEIDENTIFIER:myBounceView.invalidate();break;}super.handleMessage(msg);}};

12345678910111213141516class myThread implements Runnable {public void run() {while(!Thread.currentThread().isInterrupted()) {Message message =newMessage();message.what = TestHandler.GUIUPDATEIDENTIFIER;TestHandler.this.myHandler.sendMessage(message);try{Thread.sleep(100);}catch(InterruptedException e) {Thread.currentThread().interrupt();}}}}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值