Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2019-07-09:为什么在子线程中创建Handler会抛异常? #93

Open
Moosphan opened this issue Jul 9, 2019 · 9 comments
Open
Labels

Comments

@Moosphan
Copy link
Owner

Moosphan commented Jul 9, 2019

No description provided.

@Moosphan Moosphan added the 线程 label Jul 9, 2019
@Moosphan Moosphan changed the title 2019-07-05:为什么在子线程中创建Handler会抛异常? 2019-07-09:为什么在子线程中创建Handler会抛异常? Jul 9, 2019
@DaveBoy
Copy link

DaveBoy commented Jul 9, 2019

因为没有looper,需要先prepare

@Vicent9920
Copy link

不能在还没有调用 Looper.prepare() 方法的线程中创建 Handler
因为抛出异常的地方,在 mLooper 对象为null的时候, 会抛出异常。说明这里的Looper.myLooper();的返回值是 null。 只有调用了Looper.prepare()方法,才会构造一个Looper对象并在 ThreadLocal 存储当前线程的 Looper 对象。
这样在调用 Looper.myLooper() 时,获取的结果就不会为 null
链接:Handler的工作原理,为什么在子线程中执行 new Handler() 会抛出异常?

@18361237136
Copy link

要创建Handler必须有looper,先运行looper.prepare

@yangfanggang
Copy link

楼上说的正解,主线程默认执行了looper.prepare方法,此时使用Handler就可以往相信队列中不断进行发送消息和取出消息处理,反之没有执行looper.prepare方法,就会抛出异常,这个在源码中有所体现

所以个人感觉这么提问不是很合理,应该问为什么在子线程中不能直接创建Handler来使用?然后引出主线程默认调用looper.prepare这个会合理一点 个人意见

我是小黑 @Moosphan 沐风大佬

@android-ken
Copy link

Handler 的构造方法中,会通过Looper.myLooper()获取looper对象,如果为空,则抛出异常,主线程则因为已在入口处ActivityThread的main方法中通过 Looper.prepareMainLooper()获取到这个对象,并通过 Looper.loop()开启循环,在子线程中若要使用handler,可先通过Loop.prepare获取到looper对象,并使用Looper.loop()开启循环。

@94kai
Copy link

94kai commented Jul 11, 2019

因为代码里就是这样写的

:octocat: From gitme Android

@hyyaoming
Copy link

在子线程中创建handler需要手动创建looper。

@liliangzdh
Copy link

亲测 ,在华为 Android p8 Android 8.0 下 子线程 创建 Handler 不会闪退。预估华为做了修改,下次回答:可能在 国内一些手机不会闪退。

@mlinqirong
Copy link

mlinqirong commented Dec 15, 2021

楼上的都没有回答到点上 子线程创建Handler会抛出异常的原因是因为在looper里面ThreadLocal sThreadLocal = new ThreadLocal() ThreadLocal 就是为了保存的Looper只能在指定线程中获取Looper 因为子线程创建new Handler()并没有指定Looper 所以它就去获取ActivityThread的main方法中创建的looper 而此时的这个looper 是受线程保护的 所以子线程是无法获取的 因此抛出异常所以在子线程中没有looper 如果需要在子线程中开启handle要手动创建looper

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

10 participants