浅谈Handler
一、前言
public class GetThread1 extends Thread{ @Override public void run() { super.run(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
二是,实现接口Runable
public class GetThread2 implements Runnable{ @Override public void run() { } }
三是,直接new Thread()
new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } mytext.setText("ffff"); } }).start();
二 、正文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{ @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 1: //queryAppInfo(); break; case 2: getCompareAppInfos(isUserBigDate); break; default: break; } } }
2、Handler中分发消息的方法
postAtTime(Runnable,long)
postDelayed(Runnable long)
sendEmptyMessage(int)
sendMessage(Message)
sendMessageAtTime(Message,long)
sendMessageDelayed(Message,long)
以上post类方法允许你排列一个Runnable对象到主线程队列中,
sendMessage类方法, 允许你安排一个带数据的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 效率影响并不大.
@Override protected 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() { @Override public void onClick(View arg0) { //将线程对象从队列中移除 mhandler.removeCallbacks(mRunable); } }); /** * 创建子线程,在java中有两种方法实现线程体: * 一是,继承线程类Thread * 二是,实现接口Runable */ GetThread1 getThread1=new GetThread1(); getThread1.start(); /** * 三是 new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } mytext.setText("ffff"); } }).start(); */ }
public class GetThread1 extends Thread{ @Override public 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 的发送消息方法发送消息。 */ //第一种:obtainMessage Message 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() { @Override public 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{ @Override public 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)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:
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中发送消息,其实就是向
4)、messageQueue就是一个存储消息的容器。
为我们创建默认去创建一个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进行处理。