views:

27

answers:

0

I've got a moderately complex Android application where I'm handling rotation myself through onConfigurationChanged rather than restarting the activity. After using the device or emulator for a while (many rotations) I start to see the application laying out incorrectly intermittently (it retains it's portrait width while in landscape mode)

I added trace logging statements to all the "onAction" events in the activity and I see two distinct flows:

Correct:

  1. onConfigurationChanged
  2. onMeasure (with old width)
  3. onLayout
  4. onMeasure (with new width)
  5. onSizeChanged
  6. onLayout
  7. onDraw

When the layout is incorrect I see this flow

Incorrect:

  1. onMeasure (with new width)
  2. onSizeChanged
  3. onLayout
  4. onDraw
  5. onConfigurationChanged
  6. onMeasure (with new width)
  7. onLayout
  8. onDraw

Looking at the messages getting dispatched I think I see part of the problem: I see 3 important messages getting posted:

  • MessageType 1003 --> New Size for mWinFrame
  • MessageType 1000 --> New Measure/Layout pass (uses the size of mWinFrame)
  • MessageType 118 --> Configuration Change, kickoff a onConfigurationChanged.

When the layout is correct the order seems to be 118, 1003, 1000. When it's wrong the order seems to be 1003, 1000, 118, so it gets measured with the new width before onConfigurationChanged happens.

For extra bonus confusion, when the layout is incorrect it immediately becomes correct when I attach hierarchy viewer and dump the hierarchy, but does not become correct no matter how many times I request relayout and/or invalidate in onPreDraw.

Questions:

1) Even given the out-of-order calling, I do get the onConfigurationChanged eventually and request a relayout which happens with the new width and height, why would that not result in an update on screen?

2) Why would the posting order of those messages change over time? I never see this on a fresh boot, but start to see it when the phone / emulator has been "running for a while".