当前位置:网站首页>Looper 原理浅析
Looper 原理浅析
2022-08-09 10:54:00 【梦想改变生活】
记录一下looper 创建流程以及looper 保持主线程唯一的机制
looper 的创建是在SystemServer中创建的:
SystemServer 的main 入口
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
//其他服务的创建
Looper.prepareMainLooper();
// Loop forever.
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
在run方法中 会看到我们熟悉的两个方法:1 Looper.prepareMainLooper() 创建方法 和
2.Looper.loop(); 循环方法。下面会去剖析这两个方法写作用!
prepareMainLooper()
/** * Initialize the current thread as a looper, marking it as an * application's main looper. The main looper for your application * is created by the Android environment, so you should never need * to call this function yourself. See also: {@link #prepare()} */
public static void prepareMainLooper() {
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}
注释主要说的是,这是Looper 是主程序分配创建的,不需要开发者自己手动创建,也就是说,每个Application在创建启动的时候,都会主动在主线程创建一个looper对象。
而prepareMainLooper中主要做两件事情:1:prepare(false) 2: sMainLooper = myLooper();
1.prepare(false)
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}
通过抛出的异常可以得知:prepare 这个方法主要是为了通过ThreadLocal 保持Looper对象的唯一性的!而ThreadLocal 结构和如何保持唯一性的呢后面会专门分析的!
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
在构造方法中创建MessageQueue的作用其实就很简单了,也是为了唯一性,一个Looper对应一个MessageQueue 队列!
而Thread.currentThread() 就是获取当前线程
以上的就是Looper的创建过程 总结来说就是:
先通过ThreadLocal.get 去取,有的话 会抛出异常,没有的话会创建,创建一个looper 不是直接用的,而是先将looper 对象存入ThreadLocal中,然后通过myLooper() 去取Looper对象出来!
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
ThreadLocal
ThreadLocal 对于Looper 来说是非常的重要的,当然,不要看到Thread就觉得它是个线程,其实来说,ThreadLocal就是一个容器。下面来看看 ,在源码中ThreadLocal主要做的是什么工作的吧。
首先在Looper的全局变量中会看到这么一个:
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
这么看是不是很熟悉,其实就是一个Map!当然后面会有更多的证据去表面它就是一个Map身份
下面先看看它是如何在Looper中使用的。
在上面说到prepare中会通过sThreadLocal.get去取出Looper对象
/** * Returns the value in the current thread's copy of this * thread-local variable. If the variable has no value for the * current thread, it is first initialized to the value returned * by an invocation of the {@link #initialValue} method. * * @return the current thread's value of this thread-local */
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
注释大概意思就是通过当前线程作为key返回对应的value,而这个value就是ThreadLocalMap 对象。ThreadLocalMap是什么呢?
/** * The entries in this hash map extend WeakReference, using * its main ref field as the key (which is always a * ThreadLocal object). Note that null keys (i.e. entry.get() * == null) mean that the key is no longer referenced, so the * entry can be expunged from table. Such entries are referred to * as "stale entries" in the code that follows. */
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
ThreadLocalMap内部维护了一个key-value键值对的Entry 类! 而且是通过软引用进行引用的!
通过Entry ,而在ThreadLocal 的get方法中,通过当前本地的线程作为key 会取得当前的ThreadLocalMap,
…未完待续
边栏推荐
- caffe ---make all编辑出错
- 商业技术解决方案与高阶技术专题 - 数据可视化专题
- 遇到恶意退款不用怕,App 内购买项目的退款通知现已可用
- TensorFlow:NameError: name ‘input_data’ is not defined
- Unix Environment Programming Chapter 15 15.7 Message Queuing
- Oracle数据库常用函数总结
- Getting Started with MNIST Machine Learning
- UNIX Environment Programming Chapter 15 15.6 XSI IPC
- Julia资料收集
- 多商户商城系统功能拆解26讲-平台端分销设置
猜你喜欢
随机推荐
C语言数组题_校门外的树_标记法
golang源代码阅读,sync系列-Map
支付宝小程序的接入
数据存储:对dataframe类,使用to_csv()将中文数据写入csv文件
pip常见命令和更改源文件
解决1.tensorflow运行使用CPU不使用GPU 2.tensorflow环境下的GPU版本号 3.tensorflow和cuda以及cudnn版本对应问题 4.查看cuda和cudnn版本
Solve 1. tensorflow runs using CPU but not GPU 2. GPU version number in tensorflow environment 3. Correspondence between tensorflow and cuda and cudnn versions 4. Check cuda and cudnn versions
VBA实战(11) - 工作表(Sheet) 操作汇总
1003 Emergency (25分)
faster-rcnn中的RPN原理
使用pip成功安装某个库,但pycharm中找不到,此问题的解决方案
Probably 95% of the people are still making PyTorch mistakes
Julia资料收集
1008 Elevator (20分)
cnn的输入输出
如何在gazebo进行 joint的转动控制
在线编译matlab,亲测好用
【 original 】 VMware Workstation implementation Openwrt soft routing, the ESXI, content is very detailed!
人物 | 从程序员到架构师,我是如何快速成长的?
Getting Started with MNIST Machine Learning