文章目录

  • 一、Message 消息
  • 二、ThreadLocal 线程本地变量
  • 三、Looper 中的消息队列 MessageQueue

一、Message 消息


模仿 Android 中的 Message 基本功能 , 提供 what 与 obj 变量 , 提供一个回收方法 ;

此外 , 还要指明下一个消息 , 以及是哪个 Handler 发送的该消息 ;

package kim.hsl.handler;public class Message {/*** 消息识别码*/int what;/*** 消息对象*/Object obj;/*** 指向下一个消息*/Message next;/*** 该 Message 使用哪个 Handler 进行发送的*/Handler target;/*** 回收方法*/public void recyle(){obj = null;next = null;target = null;}
}

二、ThreadLocal 线程本地变量


ThreadLocal 作用是 保存线程私有变量 ;

使用 ThreadLocal 维护一个变量时 , 每个使用该 ThreadLocal 线程本地变量 的线程 , 都会 被分配一个独立的变量副本 ,

每个线程 只 可以 改变本线程内的 变量副本 , 即 ThreadLocal 线程本地变量 ;

1 . ThreadLocal 定义 :

    /*** 一个线程只能有一个 Looper* 使用 ThreadLocal 来保存该 Looper* 该变量是线程内部存储类 , 只能本线程才可以得到存储的数据 ;*/static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<>();

2 . ThreadLocal 变量获取 : 调用 ThreadLocal 变量的 get() 方法 , 可以获取该 ThreadLocal 线程本地变量 ;

在 ThreadLocalMap map = getMap(t) 中 , 获取的 ThreadLocalMap 与 Java 中的 Map 集合没有任何关联 , 该类就是为了保存 线程本地变量而在 ThreadLocal 中设置的内部类 ; 在该 ThreadLocalMap 内部类中 , 通过 key 键 , 获取对应 value 值 ;

public class ThreadLocal<T> {/*** 返回 该线程本地变量的 当前线程的变量副本.* 如果 该线程中对应的 变量没有值, 应该首先初始化该变量值** @return 返回当前线程的线程本地变量值 */public T get() {// 首先通过 Thread 拿到当前的线程 Thread t = Thread.currentThread();// 通过当前线程 , 获取当前线程的 ThreadLocalMap ThreadLocalMap map = getMap(t);if (map != null) {// 通过 key 获取指定的 valueThreadLocalMap.Entry e = map.getEntry(this);if (e != null) {@SuppressWarnings("unchecked")T result = (T)e.value;return result;}}return setInitialValue();}
}

3 . ThreadLocal 变量设置 : 调用 ThreadLocal 的 put() 方法 , 可以设置 线程本地变量 ;

4 . Looper 中关于 线程本地变量 的设置 : 在 Looper 中涉及到了 线程本地变量 的设置 ,

Looper 要求每个线程只能保持一个 , 并且各个线程之间的 Looper 相互独立 , 没有任何关联 ;

这就需要 将 Looper 定义成线程本地变量 ;

public class Looper {/*** 一个线程只能有一个 Looper* 使用 ThreadLocal 来保存该 Looper* 是线程内部存储类 , 只能本线程才可以得到存储的数据 ;*/static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<>();/*** 准备 Looper 方法* 其中* 使用了 sThreadLocal.get() 获取线程本地变量 * 使用了 sThreadLocal.set(new Looper()) 设置线程本地变量 */public static void prepare(){// 先进行判断 , 如果当前线程已经有了 Looper , 那就抛出异常if(sThreadLocal.get() != null){throw new RuntimeException("当前线程已存在 Looper");}// 如果不存在 Looper , 就创建一个 LoopersThreadLocal.set(new Looper());}

三、Looper 中的消息队列 MessageQueue


在 Looper 中首先要维护一个 ThreadLocal 线程本地变量 , 确保每个线程中都可以获取到一个该变量的独立副本 ;

维护消息队列 : 每个 Looper 中还要维护一个 MessageQueue 消息队列 , 用于存储从 Handler 中发送来的消息 ;

该消息队列 在 Looper 初始化时创建 ;

package kim.hsl.handler;public class Looper {/*** 一个线程只能有一个 Looper* 使用 ThreadLocal 来保存该 Looper* 是线程内部存储类 , 只能本线程才可以得到存储的数据 ;*/static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<>();/*** 消息队列*/public MessageQueue mQueue;/*** Looper 构造函数*/private Looper(){mQueue = new MessageQueue();}/*** 获取当前线程对应的 Looper* @return*/public static Looper looper(){return sThreadLocal.get();}/*** 准备 Looper 方法*/public static void prepare(){// 先进行判断 , 如果当前线程已经有了 Looper , 那就抛出异常if(sThreadLocal.get() != null){throw new RuntimeException("当前线程已存在 Looper");}// 如果不存在 Looper , 就创建一个 LoopersThreadLocal.set(new Looper());}}

【Android 异步操作】手写 Handler ( Message 消息 | ThreadLocal 线程本地变量 | Looper 中的消息队列 MessageQueue )相关推荐

  1. 【Android 异步操作】手写 Handler ( 总结 | Message | MessageQueue | Looper | Handler ) ★

    文章目录 一.Message 消息 二.Handler 消息处理者 三.MessageQueue 消息队列 四.Looper 循环者 五.关于 Looper 线程本地变量的说明 一.Message 消 ...

  2. 【Android 异步操作】手写 Handler ( Handler 发送与处理消息 | Handler 初始化 | 完整 Handler 代码 )

    文章目录 一.Handler 发送与处理消息 ( 两大功能 ) 二.Handler 初始化 三.完整 Handler 代码 一.Handler 发送与处理消息 ( 两大功能 ) Handler 有两个 ...

  3. 【Android 异步操作】手写 Handler ( 循环者 Looper | Looper 初始化 | Looper 遍历消息队列 MessageQueue )

    文章目录 一.Looper 初始化 二.Looper 遍历消息队列 MessageQueue 三.完整 Looper 代码 一.Looper 初始化 Looper 是 线程本地变量 , 在每个线程中 ...

  4. 【Android 异步操作】手写 Handler ( 消息队列 MessageQueue | 消息保存到链表 | 从链表中获取消息 )

    文章目录 一.MessageQueue 消息队列存储消息 二.MessageQueue 消息队列取出消息 三.消息队列完整代码 一.MessageQueue 消息队列存储消息 Message 链表 : ...

  5. 将tensorflow训练好的模型移植到Android (MNIST手写数字识别)

    将tensorflow训练好的模型移植到Android (MNIST手写数字识别) [尊重原创,转载请注明出处]https://blog.csdn.net/guyuealian/article/det ...

  6. android 电子签名 手写签名 功能实现

    android 电子签名  手写签名 功能实现 这个手写的效果 就是一个 重写的的自定义的view  代码如下: package com.example.hand.views;import java. ...

  7. android 手写 流畅,提高Android应用手写流畅度(基础篇)

    在使用android类的手写应用时,整体上都有这样一个印象:android的手写不流畅.不自然,和苹果应用比起来相差太远.本文结合作者亲身经历,介绍一下有效提高手写流畅度的几种方法: 1.未做任何处理 ...

  8. TF之CNN:利用sklearn(自带手写数字图片识别数据集)使用dropout解决学习中overfitting的问题+Tensorboard显示变化曲线

    TF之CNN:利用sklearn(自带手写数字图片识别数据集)使用dropout解决学习中overfitting的问题+Tensorboard显示变化曲线 目录 输出结果 设计代码 输出结果 设计代码 ...

  9. 详解线程本地变量ThreadLocal

    并发应用的一个关键地方就是共享数据.如果你创建一个类对象,实现Runnable接口,然后多个Thread对象使用同样的Runnable对象,全部的线程都共享同样的属性.这意味着,如果你在一个线程里改变 ...

最新文章

  1. 基于Chrome的扩展开发(二)
  2. 【Vue.js】vue2组件间通信方式总结
  3. Android官方开发文档Training系列课程中文版:管理Activity的生命周期之暂停和恢复Activity
  4. Notepad++中的UTF-8无BOM格式编码
  5. caffe 图片数据的转换成lmdb和数据集均值(转)
  6. Python极其简易音乐播放器
  7. Eclipse没有Web插件和JavaEE插件咋整
  8. 在计算机中打开word2010三种方法,Word2019中打开文档的三种方式
  9. xp提示计算机内存不足,虚拟内存不足怎么处理,教你电脑虚拟内存不足怎么处理...
  10. 阿里巴巴社招Java面试题做题记录
  11. 解决edge浏览器被劫持的问题 2021-02-23
  12. Calcite优化规则之ProjectAggregateMergeRule
  13. 团队管理之亮剑精神(转)
  14. 美国大学计算机专业排名2019,2019年美国大学计算机排名
  15. 最基本的顺序表(经典顺序表)
  16. 数字图像处理知识点梳理——第八章 图像压缩
  17. 计算机键盘清洗怎么弄,笔记本电脑键盘怎么清洗干净(专业户教你清洗键盘简易方法)...
  18. 整数拼接,拼成最小整数(暴力穷举)
  19. 加州伯克利计算机科学录取,2020加州大学伯克利分校统计学录取案例。
  20. DOS命令:你知道多少?

热门文章

  1. DIV与Table布局在大型网站的可用性比较
  2. 偷懒的inline-block解决方法
  3. JavaScript面向对象(一)——JS OOP基础与JS 中This指向详解
  4. VS2017 Cordova Ionic2 移动开发-环境搭建
  5. 201521123060 《Java程序设计》第10周学习总结
  6. 算法笔记_080:蓝桥杯练习 队列操作(Java)
  7. 8.Layout布局应用
  8. css之其它技巧和经验列表
  9. hive内部表与外部表区别
  10. view是怎么被展示在手机上的?