为啥不总是使用 android:configChanges="keyboardHidden|orientation"?

Posted

技术标签:

【中文标题】为啥不总是使用 android:configChanges="keyboardHidden|orientation"?【英文标题】:Why not use always android:configChanges="keyboardHidden|orientation"?为什么不总是使用 android:configChanges="keyboardHidden|orientation"? 【发布时间】:2011-12-10 17:57:45 【问题描述】:

我想知道为什么不在每个(几乎每个;))活动中使用android:configChanges="keyboardHidden|orientation"

商品:

无需担心您的活动会被轮换 更快

不太好:

如果布局取决于屏幕尺寸,则需要更改布局(例如两列左右的布局)

不好:

没有灵活的方式在不同的方向上有不同的布局 使用片段时不太好

但如果我们不使用不同的布局,为什么不呢?

【问题讨论】:

你也应该解释一下你认为keyboardHidden|orientation在做什么 它阻止使用本地处理指定的配置更改并允许应用程序处理它,不是吗? 这就是为什么有这个选项,如果你知道你在做什么(资源没有变化),使用它。 为什么比使用 ScreenSize 快? 【参考方案1】:

快速背景

默认情况下,当 Android 上发生某些关键配置更改(常见示例是方向更改)时,Android 会完全重启正在运行的 Activity 以帮助其适应此类更改。

当您在 AndroidManifest 中定义 android:configChanges="keyboardHidden|orientation" 时,您是在告诉 Android:“请不要在拔出键盘或旋转手机时进行默认重置;我想自己处理。是的,我知道我在做什么”

这是一件好事吗?我们很快就会看到...

不担心?

您开始的其中一个优点是:

无需担心您的活动被轮换

在许多情况下,人们错误地认为,当他们遇到由方向变化(“旋转”)产生的错误时,他们可以通过输入android:configChanges="keyboardHidden|orientation" 来简单地修复它。

但是,android:configChanges="keyboardHidden|orientation" 只不过是一个创可贴。事实上,可以通过多种方式触发配置更改。例如,如果用户选择了一种新的语言(即区域设置已更改),您的活动将以与方向更改相同的方式重新启动。如果您愿意,可以查看a list of all the different types of config changes。

编辑:更重要的是,正如hackbod 在 cmets 中指出的那样,当您的应用程序在后台并且 Android 决定通过杀死来释放一些内存时,您的 Activity 也将重新启动它。当用户返回您的应用程序时,Android 将尝试重新启动 Activity,就像发生其他一些配置更改时一样。如果你不能处理 - 用户将不高兴......

换句话说,使用android:configChanges="keyboardHidden|orientation" 并不能解决您的“担忧”。正确的方法是对您的活动进行编码,以便他们对 Android 向他们抛出的任何重启感到满意。这是一个很好的做法,可以帮助您走上正轨,所以要习惯它。

那么我应该什么时候使用呢?

正如您提到的,有一个明显的优势。通过自己处理来覆盖轮换的默认配置更改将加快速度。然而,这种速度确实是以便利为代价的。

简单地说,如果您对纵向和横向都使用相同的布局,那么您可以通过覆盖来保持良好状态。视图将简单地四处移动以填充剩余空间,而不是完全重新加载 Activity。

但是,如果由于某种原因您在设备处于横向时使用了不同的布局,Android 重新加载您的 Activity 的事实很好,因为它会加载正确的布局。 [如果你在这样的 Activity 上使用覆盖,并且想在运行时做一些神奇的重新布局......好吧,祝你好运 - 这远非简单]

快速总结

无论如何,如果android:configChanges="keyboardHidden|orientation" 适合您,请使用它。但是一定要测试发生变化时会发生什么,因为方向变化并不是触发完整 Activity 重启的唯一方法。

【讨论】:

值得补充的是,不处理重新启动的活动意味着您遇到的问题比不处理不太常见的配置更改要大。此处使用的 Activity 重启机制与当您的应用在后台终止时 Android 如何将您的 Activity 恢复到其先前状态的机制完全相同。因此,如果您没有正确执行此操作,您的用户会在从后台返回应用程序时随机体验到您的应用程序无法正确返回,具体取决于该进程是否恰好被终止。这是一个巨大的好处:它可以确保您的应用正确重启。 从 Android 3.x 开始不要错过添加 "screenSize" ---------- android:configChanges=["mcc", "mnc", "locale", “触摸屏”、“键盘”、“keyboardHidden”、“导航”、“screenLayout”、“fontScale”、“uiMode”、“方向”、“screenSize”、“smallestScreenSize”] 我注意到,当您使用 configChanges 属性时,您的应用也会忽略方向锁定功能。你怎么能解决这个问题?如果你知道答案,请写在这里:***.com/questions/24000361/… Please don't do the default reset when the keyboard is pulled out 我从未见过 Keyboard pull out 的 Activity 重启! 这个答案很遗憾没有提到官方Google documentation的主要解释。主要问题在于替代资源集,如果您想手动处理它,它不会在配置更改时自动为您应用。它不仅会影响有问题的 Activity,还会影响整个应用程序。【参考方案2】:

在我看来:如果横向和纵向模式下的布局相同 - 您也可以在应用中禁用两者之一。

我之所以这么说,是因为我作为用户希望应用程序在我改变方向时为我提供一些好处。如果我拿手机的方式无关紧要,那我就不需要选择了。

以您拥有 ListView 的应用为例,单击 ListItem 后,您希望看到该项目的详细视图。在横向中,您可以通过将屏幕一分为二来实现这一点,左侧是 ListView,右侧是详细视图。在 Portrait 中,您将在一个屏幕中显示列表,然后在选择 ListItem 时将屏幕更改为详细视图。在这种情况下,方向变化以及不同的布局都是有意义的。

【讨论】:

是的,我们在应用程序的 1.0 版中使用了它,以匹配我们的 Apple 版本。它仅以纵向呈现。在我的 Droid X 上看起来很棒,我们完全匹配了 ios 版本的弹出式键盘行为。然后首席财务官在他的 Droid 上安装了该应用程序,将其转到一边并滑开键盘。哎呀。 Android 的问题在于它是一个开放平台,你真的无法预测硬件配置或用户想要用它做什么,所以你应该支持两个(所有)方向以防万一。 这偶然覆盖了我们的仅纵向设置,因为基本上在硬件中横向是当时的正常方向,而不是替代方向。这真的搞砸了我们的布局:(而且非常尴尬,在他安装应用程序的几秒钟内就有一个重大缺陷 你为什么要让它的行为与 iOS 完全一样? :( @FunkTheMonk 不幸的是,我们生活在一个商人做出技术决策的世界。即使你反对它,有一半的时间他们认为他们是对的。他们控制着你的薪水。 只使用一种布局并不意味着屏幕在旋转时看起来会一样。结构良好的 XML 布局将导致事物自动转移以在合理的尺寸下正常工作,用户会欣赏这一点。【参考方案3】:

我不明白为什么......在我看来偶尔重启是可以的...... configChanges 为我处理大多数情况......也许在某些类型的应用程序中这可能是个问题,但这实际上取决于应用程序的类型和当应用程序重新启动时如何恢复状态......当我的一个应用程序重新启动时,用户被登录并且我的代码打开了最后一个活动,用户只是失去了一些步骤来回到他原来的位置但没什么大不了的......在其他一些状态是总是持续存在,并且某些状态总是在重新启动时恢复。当活动重新启动时,它必须是该应用程序尚未使用或其他什么......所以根本没有问题......例如在游戏中这可能是问题,或者在我不知道的其他类型的应用程序中......

我说当你这样做时,应用程序在正常情况下工作正常。并且代码更具可读性,无需大量的逻辑来保存和恢复,您可以在其中制造新的错误并且必须一直维护它......确定如果android断电并杀死您的应用程序窗口,它会丢失上下文和重新开始,但这仅在特殊情况下发生,并且在较新的设备上,我相信这种情况越来越少见...

所以杀了我,但我在应用程序中使用它非常成功...... android:configChanges="locale|keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" 但我知道,对于某些特殊类型的应用程序,这可能不是好方法,但大多数应用程序都可以接受。

【讨论】:

您好,了解这个主题的人可以看看我的帖子:***.com/questions/35941585/...?急需帮助。 您应该完全支持保存/恢复活动...处理它以进行轮换也不例外...您说您丢失了几步...如果操作正确,您将不会丢失任何步骤并且即使在重新启动设备后,您也可以准确地恢复用户停止的位置。 hammered 我不知道你在说什么,但我说当你这样做时,应用程序在正常情况下工作正常。并且代码更具可读性,无需大量的逻辑来保存和恢复,您可以在其中制造新的错误并且必须一直维护它......确定如果android断电并杀死您的应用程序窗口,它会丢失上下文和重新开始,但这仅在特殊情况下发生,并且在较新的设备上,我相信这种情况越来越少见... 忽略遵守 Activity 合同(保存/恢复状态)是不好的做法,这总体上是个糟糕的建议。尝试针对进程死亡进行测试,看看您的应用会在哪里找到您,如果您的用户在手机上使用至少 2-3 个应用并在它们之间切换,那么这种行为完全是标准的“正常情况”。【参考方案4】:

是的,我认为暂停会比释放播放器更快。不过还是有停顿。

现在找到了不会暂停歌曲的解决方案。

在清单中声明您将处理屏幕方向的配置更改,然后使用 onConfigurationChanged 方法加载布局文件。通过在 logCat 中执行此操作,我可以看到没有调用 onPause、onCreate 和 onResume,因此歌曲没有暂停。

    更新清单以处理方向。

    android:configChanges="orientation|screenSize"
    

    添加此代码

    @Override
    public void onConfigurationChanged(Configuration newConfig) 
        // TODO Auto-generated method stub      
        super.onConfigurationChanged(newConfig);        
        setContentView(R.layout.activity_main);
    
    

【讨论】:

您应该使用服务来播放音乐。说真的,您是在告诉人们添加仍然包含“// TODO 自动生成的方法存根”的代码。马虎的解决方案。它也不会很好地工作,你需要重新绑定所有引用,如果你不这样做,它们充其量是不可预测的。

以上是关于为啥不总是使用 android:configChanges="keyboardHidden|orientation"?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 MySQL 在这里并不总是使用索引合并?

为啥不总是使用 android:configChanges="keyboardHidden|orientation"?

为啥 Spring 在配置时并不总是使用批量插入/更新?

为啥不总是将 psyco 用于 Python 代码?

总是使用 ASP.NET 服务器控件的子类?如果不是,为啥不呢?

为啥不应该总是使用 Apache 的事件 MPM 而不是工作 MPM?