浅谈Handler
来源:互联网 发布:文案工作 知乎 编辑:程序博客网 时间:2024/04/29 10:04
浅谈Handler
一、前言
年即将过完了,眼看有到上班时间了,今年打算换个新工作,所以要准备一下面试,今天简单看了一下handler,已被面试可能会问,再次也在博客上进行一下简单的记录,言归正传,浅谈Handler........,本博客只做知识简单梳理,大神勿看。
Handler:作用,在android中,android为我们提供了handler机制,帮我们完成,接受子线程传来的数据,更新UI线程得作用,大大方便了我们的使用。并且在activity生命周期中,各个回调方法的调用中,也是用到了Handler机制,来调用各个回调方法。
ps:作为知识回顾总结:
创建线程的方式:
一是,继承线程类Thread,并重写Run()
public class GetThread1 extends Thread{@Overridepublic void run() {super.run();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}
二是,实现接口Runable
public class GetThread2 implements Runnable{@Overridepublic void run() {}}三是,直接new Thread()
new Thread(new Runnable() {@Overridepublic void run() { try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}mytext.setText("ffff");}}).start();
二 、正文Handler基本使用
Handler可以在子线程中,分发Message对象和Runable对象到主线程中,每个Handler实例,都会绑定到创建它的线程中(一般位于主线程)。
它的两个作用:(1)、 安排消息或Runnable 在某个主线程中某个地方执行,
(2)、安排一个动作在不同的线程中执行
1、创建Handler对象方式:
(1)、直接new Handler()
private Handler handler = new Handler() {public void handleMessage(android.os.Message msg) {viewPager.setCurrentItem(currentItem);// 切换当前显示的图片};};(2)、继承Handler对象
private Handler getapphandler = new getAppHandler(); class getAppHandler extends Handler{@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what) {case 1://queryAppInfo();break;case 2:getCompareAppInfos(isUserBigDate);break;default:break;}}}
2、Handler中分发消息的方法
post(Runnable)
postAtTime(Runnable,long)
postDelayed(Runnable long)
sendEmptyMessage(int)
sendMessage(Message)
sendMessageAtTime(Message,long)
sendMessageDelayed(Message,long)
以上post类方法允许你排列一个Runnable对象到主线程队列中,
sendMessage类方法, 允许你安排一个带数据的Message对象到队列中,等待更新.
postAtTime(Runnable,long)
postDelayed(Runnable long)
sendEmptyMessage(int)
sendMessage(Message)
sendMessageAtTime(Message,long)
sendMessageDelayed(Message,long)
以上post类方法允许你排列一个Runnable对象到主线程队列中,
sendMessage类方法, 允许你安排一个带数据的Message对象到队列中,等待更新.
发送Message:
Message msg;
发送一:
msg = Message.obtain(getapphandler,2);///////获取message对象
msg.sendToTarget(); ///////发送message
----------------------------------------------------------------------
Message msg = handler.obtainMessage();///////通过Handler获取message对象
msg.what = xxx;
msg.arg1 = xxx;
msg.arg2 = xxx;
msg.obj = xxx;
msg.sendToTarget(); ////发送
发送二:
Message msg = new Message()///////自己new message
msg.what = xxx;
msg.arg1 = xxx;
msg.arg2 = xxx;
handler.sendMessage(msg);////发送
性能异同比较:
建议以后创建Message对象时,使用Message msg = handler.obtainMessage();的形式创
建Message,不要自己New Message。因为此法创建,Message创建第一次时,是new的,第二三次再次使用时,
这里我们的Message 已经不是 自己创建的了,而是从MessagePool 拿的,省去了创建对象申请内存的开销。。。。。
然而发送message,使用obtainMessage 或者是 sendMessage 效率影响并不大.
Message msg;
发送一:
msg = Message.obtain(getapphandler,2);///////获取message对象
msg.sendToTarget(); ///////发送message
----------------------------------------------------------------------
Message msg = handler.obtainMessage();///////通过Handler获取message对象
msg.what = xxx;
msg.arg1 = xxx;
msg.arg2 = xxx;
msg.obj = xxx;
msg.sendToTarget(); ////发送
发送二:
Message msg = new Message()///////自己new message
msg.what = xxx;
msg.arg1 = xxx;
msg.arg2 = xxx;
handler.sendMessage(msg);////发送
性能异同比较:
建议以后创建Message对象时,使用Message msg = handler.obtainMessage();的形式创
建Message,不要自己New Message。因为此法创建,Message创建第一次时,是new的,第二三次再次使用时,
这里我们的Message 已经不是 自己创建的了,而是从MessagePool 拿的,省去了创建对象申请内存的开销。。。。。
然而发送message,使用obtainMessage 或者是 sendMessage 效率影响并不大.
实例代码:
@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mytext=(TextView) findViewById(R.id.mytext);btn_post=(Button) findViewById(R.id.btn_post);btn_post.setOnClickListener(new MyOnclickListen());btn_stop=(Button) findViewById(R.id.btn_stop);btn_stop.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View arg0) {//将线程对象从队列中移除 mhandler.removeCallbacks(mRunable);}});/** * 创建子线程,在java中有两种方法实现线程体: * 一是,继承线程类Thread * 二是,实现接口Runable */GetThread1 getThread1=new GetThread1();getThread1.start();/** * 三是 new Thread(new Runnable() {@Overridepublic void run() { try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}mytext.setText("ffff");}}).start();*/}
public class GetThread1 extends Thread{@Overridepublic void run() {super.run();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}/** * 发送Message的方式: * 获取Message方式: * 第一种写法是message 从handler 类获取,从而可以直接向该handler 对象发送消息, * Handler中obtainMessage与new Message的区别: obtainmessage()是从消息池中拿来一个msg 不需要另开辟空间new new需要重新申请,效率低,obtianmessage可以循环利用; * * 第二种写法是直接调用 handler 的发送消息方法发送消息。 *///第一种:obtainMessageMessage firstMessage=fristHandler.obtainMessage();firstMessage.obj="test1";firstMessage.sendToTarget();//第二种:sendMessage/*Message msg=new Message();msg.obj="test";Bundle b = new Bundle();// 存放数据 b.putString("color", "我的");msg.setData(b);fristHandler.sendMessage(msg);*/}}
发送三:使用post(Runnable)
/**
* 调用Handler的post()方法,将要执行的线程对象放到队列当中
*
* 这是android提供的一种机制,handler对象将通过post方法,
* 将里面的Runnable对象放到UI执行队列中,
* UI消费这个队列,调用Runnable的run方法。
*
* 虽然执行了new Runnable()这里并不生成新的线程。
* 因为Handler是绑定到UI主线程,Handler和UI主线程是同一个线程,
* HAndler的作用,主要是在其他后台线程中,通过handler这个媒介,
* 向UI主线程发送Runable对象。
*
*/
secondHandler.post(mRunable);
实例代码
private Runnable mRunable=new Runnable() {@Overridepublic void run() { //为了方便 查看,我们用Log打印出来 Log.e(TAG, Thread.currentThread().getName() + " " +count); count++; setTitle("" +count); btn_post.setText(""+count); //每2秒执行一次 mhandler.postDelayed(mRunable, 2000); }};
public class MyOnclickListen implements OnClickListener{@Overridepublic void onClick(View arg0) {/** * 调用Handler的post()方法,将要执行的线程对象放到队列当中 * * 这是android提供的一种机制,handler对象将通过post方法, * 将里面的Runnable对象放到UI执行队列中, * UI消费这个队列,调用Runnable的run方法。 * * 虽然执行了new Runnable()这里并不生成新的线程。 * 因为Handler是绑定到UI主线程,Handler和UI主线程是同一个线程, * HAndler的作用,主要是在其他后台线程中,通过handler这个媒介, * 向UI主线程发送Runable对象。 * */mhandler.post(mRunable);}}post参考:eg:http://byandby.iteye.com/blog/832467
三、Hander机制简介
1、Handler机制简述:
1)Looper: 一个线程可以产生一个Looper对象,由它来管理此线程里的Message Queue(消息队列)。
2)Handler: 你可以构造Handler对象来与Looper沟通,以便push新消息到Message Queue里;
或者接收Looper从Message Queue取出)所送来的消息。
3) Message Queue(消息队列):用来存放线程放入的消息。
4)线程:UI thread 通常就是main thread,而Android启动程序时会替它建立一个Message Queue
1)Looper: 一个线程可以产生一个Looper对象,由它来管理此线程里的Message Queue(消息队列)。
2)Handler: 你可以构造Handler对象来与Looper沟通,以便push新消息到Message Queue里;
或者接收Looper从Message Queue取出)所送来的消息。
3) Message Queue(消息队列):用来存放线程放入的消息。
4)线程:UI thread 通常就是main thread,而Android启动程序时会替它建立一个Message Queue
2、handler的原理:
handler封装了消息的发送,主要包括消息发送给谁。
1)、Looper:
activityThread创建Ui线程时,通过ThreadLocal.set(new Lopper),set了Looper对象,
a、内部包含了一个消息队列也就是messageQueue,所有handler发送的消息都走向了消息队列。
b、通过looper.looper方法,就是一个死循环,不断从messageQueue去消息,如果有消息就处理,没消息就阻塞。
2)、MessageQueue:
就是一个消息队列,可以添加消息,并处理消息。
3)、Handler:
handler构造函数内部会跟Looper进行关联,即通过上面的ThreadLocal.get()得到Looper对象,也就是说在handler的内部可以找到Looper,找到Looper也就找到MessageQueue,在handler中发送消息,其实就是向handler负责发送消息,looper负责接收handler发送的消息,并直接把消息回传给hanndler自己。
4)、messageQueue就是一个存储消息的容器。
1)、Looper:
activityThread创建Ui线程时,通过ThreadLocal.set(new Lopper),set了Looper对象,
a、内部包含了一个消息队列也就是messageQueue,所有handler发送的消息都走向了消息队列。
b、通过looper.looper方法,就是一个死循环,不断从messageQueue去消息,如果有消息就处理,没消息就阻塞。
2)、MessageQueue:
就是一个消息队列,可以添加消息,并处理消息。
3)、Handler:
handler构造函数内部会跟Looper进行关联,即通过上面的ThreadLocal.get()得到Looper对象,也就是说在handler的内部可以找到Looper,找到Looper也就找到MessageQueue,在handler中发送消息,其实就是向handler负责发送消息,looper负责接收handler发送的消息,并直接把消息回传给hanndler自己。
4)、messageQueue就是一个存储消息的容器。
当你创建一个进程的时候,就回创建一个main线程,也就是activityThread线程,activityThread线程会在系统之中,
为我们创建默认去创建一个looper,Looper就回和MessageQuenen和UI线程,有联系。主线程运行MessageQuenene.
UI主线程初始化第一个Handler时会通过ThreadLocal创建一个Looper,
该Looper与UI主线程一一对应。使用ThreadLocal的目的是保证每一个线程只创建唯一一个Looper。
之后其他Handler初始化的时候直接获取第一个Handler创建的Looper。Looper初始化
的时候会创建一个消息队列MessageQueue。至此,主线程、消息循环、消息队列之间的关系是1:1:1。
Handler、Looper、MessageQueue的初始化流程如图所示:
Hander持有对UI主线程消息队列MessageQueue和消息循环Looper的引用,
子线程可以通过Handler将消息发送到UI线程的消息队列MessageQueue中。
UI主线程通过Looper循环查询消息队列UI_MQ,
当发现有消息存在时会将消息从消息队列中取出。
首先分析消息,通过消息的参数判断该消息对应的Handler,
然后将消息分发到指定的Handler进行处理。
为我们创建默认去创建一个looper,Looper就回和MessageQuenen和UI线程,有联系。主线程运行MessageQuenene.
UI主线程初始化第一个Handler时会通过ThreadLocal创建一个Looper,
该Looper与UI主线程一一对应。使用ThreadLocal的目的是保证每一个线程只创建唯一一个Looper。
之后其他Handler初始化的时候直接获取第一个Handler创建的Looper。Looper初始化
的时候会创建一个消息队列MessageQueue。至此,主线程、消息循环、消息队列之间的关系是1:1:1。
Handler、Looper、MessageQueue的初始化流程如图所示:
Hander持有对UI主线程消息队列MessageQueue和消息循环Looper的引用,
子线程可以通过Handler将消息发送到UI线程的消息队列MessageQueue中。
UI主线程通过Looper循环查询消息队列UI_MQ,
当发现有消息存在时会将消息从消息队列中取出。
首先分析消息,通过消息的参数判断该消息对应的Handler,
然后将消息分发到指定的Handler进行处理。
欧了!!!!!!!!!!!!!!!!
0 0
- 浅谈Handler
- 浅谈Handler
- 浅谈handler
- handler浅谈
- 浅谈Handler
- android Handler浅谈
- Handler消息机制浅谈
- 浅谈handler使用机制
- 浅谈Android Handler
- 浅谈Android中的Handler
- 浅谈Android Handler机制
- 浅谈Handler机制
- Handler的基本原理浅谈
- 浅谈Handler机制
- Handler机制浅谈
- Handler消息机制浅谈
- 浅谈Android Handler 消息机制
- 浅谈Android中的Handler机制
- BZOJ 1188 [HNOI 2007]分裂游戏 (博弈)
- ORACLE 11G 官方文档演示:查找手工建库语句
- pat1029 Median
- DP入门50题(5)——NYoj 17 单调递增最长子序列
- Binary Tree Preorder Traversal
- 浅谈Handler
- 1010. Radix (25)
- CF 457A(Golden System-特殊的进制)
- 并查集(hdu5176)
- 程序员必读书单
- "this whole ARM thing is a f*cking pain in the ass"
- Python 开发者应该知道的 7 个开发库(转)
- HDU 2807解题报告
- shell 脚本编程