处理程序,MessageQueue,活套,也都在UI线程上运行吗? [英] Handlers, MessageQueue, Looper, do they all run on the UI thread?

查看:250
本文介绍了处理程序,MessageQueue,活套,也都在UI线程上运行吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想换行我的头周围线程,我知道我可以使用处理程序发布的消息/可运行于 MessageQueue ,这反过来又被拾起,尺蠖并送回处理程序进行处理。

什么我不能完全肯定就是这个东西正在发生的事情。更多precicely:如果我上传到我的活动处理程序,是活动处理程序 MessageQueue 尺蠖在UI线程上所有正在运行的?如果不是,可能有人请解释这一切是如何走到一起? :)

解决方案

简短的回答:的他们都在同一个线程运行。如果从活动实例生命周期回调,他们的主UI线程中运行。

的回答:

一个线程可能有一个尺蠖,其中包含一个 MessageQueue 为了使用这个工具,你必须创建一个尺蠖通过调用当前线程(静态)活套。prepare(),然后通过调用启动循环(也静态) Looper.loop()。这些都是静态的,因为有只应该是一个尺蠖每个线程。

)的调用循环(通常不会返回有一段时间了,但一直服用的消息(任务,命令或不管你喜欢叫他们)从 MessageQueue ,并单独处理它们(通过调用回的Runnable 包含在如该消息)。当没有留在队列中的消息,该线程阻塞,直到有新的消息。要停止尺蠖,你必须调用退出()就可以了(这可能不会立即停止循环,而是设置一个从循环定期检查,标志着其停止)的私人标志。

<打击>但是,你可以不排队直接添加消息。相反,你注册一个 MessageQueue.IdleHandler 来等待 queueIdle()回调,您可以在其中,如果你决定想要的东西或没有。所有的处理程序依次调用。 (所以的队列是不是一个真正的队列,而是回调集合定期名为。)

<打击>的有关previous段注:的这个我其实猜到了。我无法找到任何文件,但它是有意义的。

更新:查看<一href="http://stackoverflow.com/questions/5193913/handlers-messagequeue-looper-do-they-all-run-on-the-ui-thread/9638823#comment12235187_5193981">ahcox'评论和<一href="http://stackoverflow.com/questions/5193913/handlers-messagequeue-looper-do-they-all-run-on-the-ui-thread/9638823#9638823">his回答。

由于这是很多的工作,该框架提供了 处理程序类来简化事情。当你创建一个处理程序实例,它是绑定到弯针(默认)已连接到当前线程。 (该处理程序知道尺蠖来重视,因为我们叫 prepare() 较早,这可能存储在的ThreadLocal )尺蠖 P>

随着 处理程序,你可以叫后() 以放一个消息到线程的消息队列(这么说)。该处理程序将采取一切 IdleHandler 回调的东西照顾,并确保您发布的的Runnable 执行。 (这也可能检查的时间是正确的已经,如果贴有一个延迟。)

只是要清楚:只有这样,才能真正发挥循环线程的执行的东西来发布消息,它的循环。这是有效的,直到调用退出()上的弯针。


关于Android的UI线程:在某些时候(可能是之前的任何活动等的创建)的框架内成立了一个尺蠖 (含 MessageQueue ),并启动它。从这个角度上,所发生的一切UI线程是通过循环。这包括活动的生命周期管理等。所有的回调函数,你覆盖(的onCreate()的onDestroy() ...)至少indirecty从环出动。你可以看到,例如在出现异常的堆栈跟踪。 (你可以尝试一下,只写 INT A = 1/0; 介于的onCreate() ...)


我希望这是有道理的。对不起,我是不清楚previously。

I'm trying to wrap my head around threading, and I know that I may use a Handler to post messages/runnables to the MessageQueue, which in turn gets picked up by the Looper and sent back to the Handler for processing.

What I'm not entirely sure of is where this stuff is happening. More precicely: If I post to a handler in my activity, is the Activity, Handler, MessageQueue and Looper all running on the UI thread? If not, could someone please explain how this all comes together? :)

解决方案

Short answer: they all run on the same thread. If instantiated from an Activity lifecycle callback, they all run on the main UI thread.

Long answer:

A thread may have a Looper, which contains a MessageQueue. In order to use this facility, you would have to create a Looper on the current thread by calling (the static) Looper.prepare(), and then start the loop by calling (the also static) Looper.loop(). These are static because there is only supposed to be one Looper per thread.

The call to loop() usually does not return for some time, but keeps taking messages ("tasks", "commands" or whatever you like to call them) out of the MessageQueue and handles them individually (e.g. by calling back a Runnable contained in the message). When there are no messages left in the queue, the thread blocks until there are new messages. To stop a Looper, you have to call quit() on it (which probably does not stop the loop immediately, but rather sets a private flag that is checked periodically from the loop, signaling the it to stop).

However, you cannot add messages to the queue directly. Instead, you register a MessageQueue.IdleHandler to wait for a queueIdle() callback, in which you can decide if you wish to to something or not. All handlers are called in turn. (So the "queue" isn't really a queue, but instead a collection of callbacks to be called regularly.)

Note regarding the previous paragraph: This I actually guessed. I couldn't find any documentation on that, but it would make sense.

update: see ahcox' comment and his answer.

Because this is a lot of work, the framework provides the Handler class to simplify things. When you create a Handler instance, it is (by default) bound to the Looper already attached to the current thread. (The Handler knows what Looper to attach to because we called prepare() earlier, which probably stored a reference to the Looper in a ThreadLocal.)

With a Handler, you can just call post() to "put a message into the thread's message queue" (so to speak). The Handler will take care of all the IdleHandler callback stuff and make sure your posted Runnable is executed. (It might also check if the time is right already, if you posted with a delay.)

Just to be clear: the only way to actually make a looping thread do something is to post a message to it's loop. This is valid until you call quit() on the looper.


Regarding the android UI thread: At some point (probably before any activities and the like are created) the framework has set up a Looper (containing a MessageQueue) and started it. From this point on, everything that happens on the UI thread is through that loop. This includes activity lifecycle management and so on. All callbacks you override (onCreate(), onDestroy()...) are at least indirecty dispatched from that loop. You can see that for example in the stack trace of an exception. (You can try it, just write int a = 1 / 0; somewhere in onCreate()...)


I hope this makes sense. Sorry for being unclear previously.

这篇关于处理程序,MessageQueue,活套,也都在UI线程上运行吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆