performTraversals和onConfigurationChanged中的竞争条件会导致布局错误吗?

时间:2010-07-08 15:02:51

标签: android screen-rotation

我有一个中等复杂的Android应用程序,我通过onConfigurationChanged处理轮换,而不是重新启动活动。使用设备或仿真器一段时间后(多次旋转)我开始看到应用程序间歇性地错误布局(在横向模式下它保留了纵向宽度)

我在活动中的所有“onAction”事件中添加了跟踪日志记录语句,我看到了两个不同的流程:

正确:

  1. onConfigurationChanged
  2. onMeasure (旧宽度)
  3. onLayout
  4. onMeasure (新宽度)
  5. onSizeChanged
  6. onLayout
  7. 的onDraw
  8. 当布局不正确时,我会看到此流程

    不正确:

    1. onMeasure (新宽度)
    2. onSizeChanged
    3. onLayout
    4. 的onDraw
    5. onConfigurationChanged
    6. onMeasure (新宽度)
    7. onLayout
    8. 的onDraw
    9. 查看已发送的消息我认为我看到了部分问题:我看到有3条重要消息被发布:

      • MessageType 1003 - > mWinFrame的新尺寸
      • MessageType 1000 - >新的度量/布局传递(使用mWinFrame的大小)
      • MessageType 118 - >配置更改,启动onConfigurationChanged。

      当布局正确时,顺序似乎是118,1003,1000。当它出错时,顺序似乎是1003,1000,118,所以在onConfigurationChanged发生之前用新宽度测量它。

      对于额外的奖金混淆,当布局不正确时,当我附加层次结构查看器并转储层次结构时它立即变得正确,但无论我在onPreDraw中请求重新布局和/或无效多少次都不正确。

      问题:

      1)即使给出了无序调用,我最终还是得到了onConfigurationChanged并请求一个新的宽度和高度的重新布局,为什么这不会导致屏幕上的更新?

      2)为什么这些消息的发布顺序会随着时间而变化?我从来没有在新的启动时看到这个,但是当电话/模拟器“运行一段时间”时就开始看到它。

1 个答案:

答案 0 :(得分:0)

这似乎更常发生在较慢的手机上,绕过它的一种方法是在onPause()中执行可怕的kludge ... setVisible(false)并发布Runnable来执行setVisible(true)onResume()。

这使得它有时间在测量/布局之前注册正确的高度,你的层次结构查看线索表明有一种神奇的方法,可能不是这个方法,但至少它似乎现在用胶带来解决问题。