当前位置:网站首页>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,
…未完待续
边栏推荐
猜你喜欢
随机推荐
torch.stack()的官方解释,详解以及例子
Netscope:神经网络结构在线可视化工具
linux mysql操作的相关命令
tensor.eq() tensor.item() tensor.argmax()
unix环境编程 第十五章 15.3 函数popen和pclose
unix系统编程 第十五章 15.2管道
autogluon安装,使用指南,代码
Jmeter BeanShell post processor
kubernetes中不可见的OOM
golang interface “坑记录“
unix环境编程 第十四章 14.8 存储映射I/O
性能测试(03)-JDBC Request
力扣(LeetCode)220. 存在重复元素 III(2022.08.08)
日期工具类
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
985毕业,工作3年,分享从阿里辞职到了国企的一路辛酸和经验
无重复字符的最长子串
verbose np.matmul/np.dot/np.multiply/tf.matmul/tf.multiply/*
VBA实战(11) - 工作表(Sheet) 操作汇总
程序员的专属浪漫——用3D Engine 5分钟实现烟花绽放效果









