Android UI线程消息队列调度顺序

时间:2021-12-13 00:06:48

While working with retain Fragments in Android to hold an AsyncTask during configuration changes, which i guess it's the best approach, some doubts appear in my mind about UI Thread's Message Queue invocation order.

虽然在配置更改期间使用Android中的retain Fragments来保存AsyncTask,我认为这是最好的方法,但我脑海中出现了一些关于UI Thread的Message Queue调用顺序的疑问。

Ex: Imagine this scenario:

例如:想象一下这种情况:

  1. Configuration Change occurs, user rotates the device. AsyncTask is running.
  2. 发生配置更改,用户旋转设备。 AsyncTask正在运行。
  3. Fragment onDetach() is called
  4. 调用片段onDetach()
  5. AsyncTask doInBackground() method finishes
  6. AsyncTask doInBackground()方法完成
  7. AsyncTask onPostExecute()is called
  8. 调用AsyncTask onPostExecute()
  9. Fragment onAttach() is called
  10. 调用片段onAttach()

So can UI Thread Message Queue be like this:

UI线程消息队列也可以这样:

Queue top -> onDetach() | onPostExecute() | onAttach()

队列顶部 - > onDetach()| onPostExecute()| onAttach()

I know it cannot, the call to onPostExecute() will wait until the configuration change completes, as far as i know, but how does that work ? Are the calls from Activities, Fragments life-cycles executed consecutively ?

我知道它不能,对onPostExecute()的调用将等到配置更改完成,据我所知,但这是如何工作的?来自活动,碎片生命周期的调用是否连续执行?

1 个解决方案

#1


107  

It is not possible for onPostExecute() to be called in between Fragment#onDetach() and Fragment#onAttach() during a configuration change. The reasoning behind this claim is threefold:

在配置更改期间,无法在Fragment#onDetach()和Fragment#onAttach()之间调用onPostExecute()。这种说法背后的原因有三个:

  1. Configuration changes are handled inside a single message in the main thread's message queue.

    配置更改在主线程的消息队列中的单个消息内处理。

  2. As soon as the doInBackground() method returns, the AsyncTask schedules the onPostExecute() method to be invoked on the main thread by posting a message to the main thread's message queue.

    一旦doInBackground()方法返回,AsyncTask就会通过向主线程的消息队列发送消息来调度在主线程上调用的onPostExecute()方法。

  3. The configuration change's message will contain the code that will invoke the Activity and Fragment lifecycle methods (such as onDetach() and onAttach()). The AsyncTask's message will contain the code that will invoke the onPostExecute() method. Since the main thread processes messages in its message queue sequentially, it is impossible for the two messages to be executed at the same time, and therefore onPostExecute() can never be invoked in between the calls to onDetach() and onAttach().

    配置更改的消息将包含将调用Activity和Fragment生命周期方法的代码(例如onDetach()和onAttach())。 AsyncTask的消息将包含将调用onPostExecute()方法的代码。由于主线程按顺序处理消息队列中的消息,因此两个消息不可能同时执行,因此在onDetach()和onAttach()的调用之间永远不能调用onPostExecute()。

Read my response to Doug Stevenson in this thread for a more detailed explanation (including links to the source code that prove the claim).

请阅读我在此主题中对Doug Stevenson的回复,以获得更详细的解释(包括证明声明的源代码的链接)。

#1


107  

It is not possible for onPostExecute() to be called in between Fragment#onDetach() and Fragment#onAttach() during a configuration change. The reasoning behind this claim is threefold:

在配置更改期间,无法在Fragment#onDetach()和Fragment#onAttach()之间调用onPostExecute()。这种说法背后的原因有三个:

  1. Configuration changes are handled inside a single message in the main thread's message queue.

    配置更改在主线程的消息队列中的单个消息内处理。

  2. As soon as the doInBackground() method returns, the AsyncTask schedules the onPostExecute() method to be invoked on the main thread by posting a message to the main thread's message queue.

    一旦doInBackground()方法返回,AsyncTask就会通过向主线程的消息队列发送消息来调度在主线程上调用的onPostExecute()方法。

  3. The configuration change's message will contain the code that will invoke the Activity and Fragment lifecycle methods (such as onDetach() and onAttach()). The AsyncTask's message will contain the code that will invoke the onPostExecute() method. Since the main thread processes messages in its message queue sequentially, it is impossible for the two messages to be executed at the same time, and therefore onPostExecute() can never be invoked in between the calls to onDetach() and onAttach().

    配置更改的消息将包含将调用Activity和Fragment生命周期方法的代码(例如onDetach()和onAttach())。 AsyncTask的消息将包含将调用onPostExecute()方法的代码。由于主线程按顺序处理消息队列中的消息,因此两个消息不可能同时执行,因此在onDetach()和onAttach()的调用之间永远不能调用onPostExecute()。

Read my response to Doug Stevenson in this thread for a more detailed explanation (including links to the source code that prove the claim).

请阅读我在此主题中对Doug Stevenson的回复,以获得更详细的解释(包括证明声明的源代码的链接)。