从零了解Android消息机制

本着深入浅出的原则,本文详细介绍了从线程到Handler消息传递机制的内容,中间多引用博客,如果不了解,还是要详细看下链接里面的内容,适合像我这种基础不扎实的同学学习下。

首先,废话下为什么要有异步任务:
如果在主线程(UI线程)操作一些耗时的操作容易造成卡顿,
Android 规定主线程中不可以做耗时操作(访问网络,操作数据库)

现在最基础的异步任务的使用方法:
1.使用Handler消息传递机制;
2.使用AsyncTask异步任务;

要是这时候你不熟悉实现多线程的方式,请狂点
java线程系列---Runnable和Thread的区别

结论:
实现方式是1.实现Runnable接口 2.继承Thread类
多线程肯定永远以实现Runnable接口为主
使用Runnable实现多线程可以达到资源共享目的
另外,Thread类也是Runnable亲儿子

要是这时候你不能随手写出Handler的实现方式,请狂点
Android Handler详细使用方法实例

用法:
1.将handler绑定到它所建立的线程中,简单粗暴没情趣

    //使用handler时首先要创建一个handler(UI线程)
    Handler handler = new Handler();

    //将线程接口立刻送到线程队列中
    handler.removeCallbacks(update_thread);

    Runnable update_thread = new Runnable()
    {
        public void run()
        {
            //UI操作
        }
    };
    handler.post(update_thread);
    //将接口从线程队列中移除

2.handler的消息队列机制,慢条斯理前戏足

    // 调用:
    update_progress_handler.post(update_thread);

    //创建一个handler,内部完成处理消息方法
    Handler update_progress_handler = new Handler()
    {
        @Override
        public void handleMessage(Message msg) {
            // UI线程
            // msg.arg1 = "bilibili"
        }
    };

    Runnable update_thread = new Runnable()
    {
        public void run() {
            Message msg = update_progress_handler.obtainMessage();
            //把消息发送到消息队列中,msg对应handleMessage的入参
            msg.arg1 = "bilibili";
            update_progress_handler.sendMessage(msg);
        }
    };

    //移除
    update_progress_handler.removeCallbacks(update_thread);

3.自己看链接吧...

handler.sendMessage(msg) 和 handler.post(Runnable) 都知道什么情况下用了,接下来就是硬菜了

请狂点:
Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系

结论

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)最终调用的方法

还有需要注意的,因为最终调用的方法都是这个

public void dispatchMessage(Message msg) {  
      if (msg.callback != null) { 
          handleCallback(msg);  
      } else {  
          if (mCallback != null) {  
              if (mCallback.handleMessage(msg)) {  
                  return;  
              }  
          }  
          handleMessage(msg);  
      }  
  } 

分发消息流程:

当Message的msg.callback不为空时,则回调方法msg.callback.run();
当Handler的mCallback不为空时,则回调方法mCallback.handleMessage(msg);
最后调用Handler自身的回调方法handleMessage(),该方法默认为空,Handler子类通过覆写该方法来完成具体的逻辑。

消息分发的优先级:

Message的回调方法:message.callback.run(),优先级最高;
Handler中Callback的回调方法:Handler.mCallback.handleMessage(msg),优先级仅次于1;
Handler的默认方法:Handler.handleMessage(msg),优先级最低。

对于很多情况下,消息分发后的处理方法是第3种情况,即Handler.handleMessage(),一般地往往通过覆写该方法从而实现自己的业务逻辑。

懵懵懂懂是嘛?换个方向给你说一遍,补充下内容,能更好的了解整个过程
Android消息机制的原理剖析—闭环总结

结论

(a)MessageQueue和Looper:一对一关系,MessageQueue的创建后放置在Looper中。
(b)Looper和线程:一个线程只有一个,创建之后保存在ThreadLocal中,想要获取ThreadLocal.get()即可。
(c)Handler和Looper:Handler创建时候,从ThreadLocal中获取Looper,Handler变量指向这个Looper,Handler和Looper绑定。
(d)Message和Handler:Handler发送Message时候,Message的target属性指向这个Handler,也是这个Handler来分发处理这个Message
(e)消息池:only one,所有线程共享。

现在Android的消息机制都玩的溜了,不过对于偶尔用到一次用到就要考虑什么异步消息处理机制,还要专门使用一个Handler来发送和接收消息,就好比每次哄好了好不容易脱光了衣服还要先洗澡一样...

这个时候,就必须要学会AsyncTask了
Android AsyncTask完全解析,带你从源码的角度彻底理解

强突:

 * 执行次序    执行时机        方法名称           调用方
 *  1        异步任务执行前   onPreExecute      UI线程
 *  2        异步任务执行中   doInBackground    后台线程
 *  3        异步任务执行中   publishProgress   后台线程
 *  4        异步任务执行中   onProgressUpdate    UI线程
 *  5        异步任务执行后   onPostExecute       UI线程

使用:

private class MyTask extends AsyncTask {
        @Override
        protected void onPreExecute() {
            //onPreExecute方法用于在执行后台任务前做一些UI操作
        }

        //doInBackground方法内部执行后台任务,不可在此方法内修改UI
        @Override
        protected String doInBackground(String... params) {
            //doInBackground方法内部执行后台任务,不可在此方法内修改UI
            // 后台线程向UI线程发布进度状态
            publishProgress(i);
            return null;
        }

        @Override
        protected void onProgressUpdate(Integer... progresses) {
            //onProgressUpdate方法用于更新进度信息
        }

        @Override
        protected void onPostExecute(String result) {
            //onPostExecute方法用于在执行完后台任务后更新UI,显示结果
        }

        @Override
        protected void onCancelled() {
            //onCancelled方法用于在取消执行中的任务时更改UI
        }
    }

调用:

               //注意每次需new一个实例,新建的任务只能执行一次,否则会出现异常
                mTask = new MyTask();
                mTask.execute();

                //取消一个正在执行的任务,onCancelled方法将会被调用
                mTask.cancel(true);

结论:

AsyncTask也是使用的异步消息处理机制,只是做了非常好的封装

你可能感兴趣的:(从零了解Android消息机制)