Handler

几个关键概念

MessageQueue

MessageQueue:是一种数据结构,就是一个消息队列,存放消息的地方。每一个线程最多只可以拥有一个MessageQueue数据结构
MessageQueue对象不需要我们自己创建。通常使用一个Looper对象对该线程的MessageQueue进行管理。
主线程创建时,会创建一个默认的Looper对象,而Looper对象的创建,将自动创建一个Message Queue。
其他非主线程,不会自动创建Looper,要需要的时候,通过调用prepare函数来实现。
我们可以通过Looper.myQueue()获取当前线程中的MessageQueue。

Message

Message:消息对象,Message Queue中的存放的对象。一个Message Queue中包含多个Message,按照“先进先出”的原则存放消息。
使用Message时,我们可以通过new Message()创建一个Message实例,但是Android更推荐我们通过Message.obtain()或者Handler.obtainMessage()获取Message对象 Message它的创建并不一定是直接创建一个新的实例,而是先从Message Pool(消息池)中看有没有可用的Message实例,存在则直接取出返回这个实例。如果Message Pool中没有可用的Message实例,则才用给定的参数创建一个Message对象。
调用removeMessages()时,将Message从Message Queue中删除,同时放入到Message Pool中。
使用消息池的好处是:消息不被使用时,并不作为垃圾回收,而是放入消息池,可供下次Handler创建消息时使用。消息池提高了消息对象的复用,减少系统垃圾回收的次数

Looper:

Looper: 是MessageQueue的管理者。每一个MessageQueue都不能脱离Looper而存在,Looper对象的创建是通过prepare函数来实现的。同时每一个Looper对象和一个线程关联。通过调用Looper.myLooper()可以获得当前线程的Looper对象
创建一个Looper对象时,会同时创建一个MessageQueue对象。除了主线程有默认的Looper,其他线程默认是没有Looper对象的。
Looper主要是prepare()和loop()两个方法
prepare() 创建Looper对象和MessageQueue数据结构
loop() 不断从MessageQueue中去取消息,交给消息的target属性的dispatchMessage去处理。
如果想让我们新创建的线程拥有Looper对象时,我们首先应调用Looper.prepare()方法,然后再调用Looper.loop()方法。典型的用法如下:

class LooperThread extends Thread
{
  public Handler mHandler;
  public void run()
  {
    Looper.prepare();
    //其它需要处理的操作
    Looper.loop();
  }
}

Handler

Handler: 消息的处理者。
Message获取:new Message(),或者Message.obtain()或者Handler.obtainMessage()
handler对象的sendMessage(msg)将Message传递给Looper,继而由Looper将Message放入MessageQueue中。
Looper循环查询消息队列MessageQueue,当发现有消息存在时会将消息从消息队列中取出。首先分析消息,通过消息的参数判断该消息对应的Handler,然后就会调用该Message对象对应的handler对象的handleMessage()方法对其进行处理

流程:

1、首先Looper.prepare()在本线程中保存一个Looper实例,然后该实例中保存一个MessageQueue对象;因为Looper.prepare()在一个线程中只能调用一次,所以MessageQueue在一个线程中只会存在一个。
2、Looper.loop()会让当前线程进入一个无限循环,不端从MessageQueue的实例中读取消息,然后回调msg.target.dispatchMessage(msg)方法。
3、Handler的构造方法,会首先得到当前线程中保存的Looper实例,进而与Looper实例中的MessageQueue想关联。
4、Handler的sendMessage方法,会给msg的target赋值为handler自身,然后加入MessageQueue中。
5、在构造Handler实例时,我们会重写handleMessage方法,也就是msg.target.dispatchMessage(msg)最终调用的方法。

Handler的特点

Handler可以分发Message对象(通过sendMessage)和Runnable对象(通过post())到主线程中, 每个Handler实例,都会绑定到创建他的线程中,
它有两个作用:
1 发送消息Message到消息队列中,
2 handleMessage()处理消息
注:post(Runnable)实质也是发送消息Message(Runnable转化成一个Message)到消息队列中,处理是会直接调用run().

post(Runnable)
postAtTime(Runnable,long)
postDelayed(Runnable long)
sendEmptyMessage(int)
sendMessage(Message)
sendMessageAtTime(Message,long)
sendMessageDelayed(Message,long)
以上post类方法允许你发送一个Runnable对象(Runable对象作为callback属性,赋值给了此message,Runnable转化成一个Message)到该创建handle线程的消息队列中。
sendMessage类方法, 允许你发送一个带数据的Message对象到消息队列中.

Handler post

mHandler.post(new Runnable()  
{  
    @Override  
    public void run()  
    {  
        Log.e("TAG", Thread.currentThread().getName());  
        mTxt.setText("yoxi");  
    }  
});  

然后run方法中可以写更新UI的代码,其实这个Runnable并没有创建新线程,而是发送了一条消息。Runable对象作为callback属性,赋值给了message,Runnable转化成一个Message。
handler会在looper中调用这个Runnable的Run方法执行。
Runnable没有启动(线程的启动是用start()来启动的所以没有创建新线程。

代码参考

private Handler splashHandler = new Handler() {
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case OVER:
                progressDialog.dismiss();
                break;
            default:
                break;
        }
        super.handleMessage(msg);
    }
}; 

new Thread() {public void run() {
    initList();
    Message m = splashHandler.obtainMessage(OVER);
    splashHandler.sendMessage(m);
    splashHandler.post(r);
    splashHandler.postDelayed(r, delayMillis);
    splashHandler.postAtTime(r, uptimeMillis);

}}.start();
//也可以直接使用
splashHandler.post(new Runnable(){
    public void run() {
    //直接跟新
        progressDialog.dismiss();
    }
});
//handle+Thread:线程中发送消息,主线程handle处理消息
//Handler.post直接在主创建该handler线程中处理

AsyncTask实现的原理和适用的优缺点

AsyncTask,是Android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程.
使用的优点:
简单,快捷
过程可控
使用的缺点:
在使用多个异步操作和并需要进行Ui变更时,就变得复杂起来.

Handler异步实现的原理和适用的优缺点

在Handler 异步实现时,涉及到 Handler, Looper, Message,Thread四个对象,实现异步的流程是主线程启动Thread(子线程)运行并生成Message-Looper获取Message并传递给HandlerHandler逐个获取Looper中的Message,并进行UI变更。
使用的优点:
结构清晰,功能定义明确
对于多个后台任务时,简单,清晰
使用的缺点:
在单个后台异步处理时,显得代码过多,结构过于复杂(相对性)

Android的AsyncTask比Handler更轻量级一些(只是代码上轻量一些,而实际上要比handler更耗资源),适用于简单的异步处理。
首先明确Android之所以有Handler和AsyncTask,都是为了不阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值