5

我使用了这两种方法:

  1. 让活动在旋转时被销毁
  2. 不要让活动在轮换时被破坏

我的方法几乎每次都是捕捉旋转事件,如果需要,调用 setContentView 并再次添加一些组件。如果没有,只需让它旋转,布局就会适应。

到目前为止,我只看到让它在具有非常复杂的结构且非常动态的屏幕上被破坏的优势,并且每当我旋转而不是破坏时,在重新构建屏幕时会显示一些闪烁。

必须通过 onSaveInstance 和 onRestoreInstace 传递状态的开销有时非常容易出错,并且在某种程度上很耗时。

我错过了什么吗?

更新:

如果“Orientation.XPTO == ...”在我的代码上,我没有做任何类型的事情。这是两种方法中的每一种的逻辑(代码被重用):

破坏时

onCreate -> DrawUI() setContentView and add views -> fill() add content

未销毁时:

onCreate -> DrawUI() setContentView and add views -> fill() add content
onRotation -> DrawUI() setContentView and add views -> fill() add content

在旋转后调用 setContentView 时,它将为设备方向选择正确的布局(通过 Google 的 Reto Meier https://stackoverflow.com/a/456918/327011检查此答案)

并且 DrawUI 和填充必须具有纵向和横向布局的逻辑,因为可以在两个方向中的每一个上创建活动。

4

5 回答 5

10

我错过了什么吗?

是的。您假设您的替代方案不太容易出错。

通过不经历销毁和重新创建周期,您必须确保针对每个可能的配置更改处理更改每个资源。

不要让活动在轮换时被破坏

除非您使用android:screenOrientation强制您的活动进入单一方向(例如,landscape),否则您不能只处理与旋转相关的配置更改。您需要处理所有配置更改。否则,一旦用户将他们的设备放入扩展坞、将其从扩展坞中移除、从“设置”更改语言、附加或分离键盘、更改全局字体缩放等,您的应用程序就会崩溃。

反过来,这意味着在每次配置更改时,您都需要:

  • 为可能的新字符串资源更新 UI
  • 调整或重新加载您的布局(并通过“调整”,包括更改任何可绘制对象、动画、菜单等)
  • 与您的资源相关的任何其他内容(例如,您的数组列表PreferenceFragment

问题是你会忘记一些东西。例如,您将错过更改与操作栏项关联的字符串,因此现在您的大部分 UI 都是西班牙语,而操作栏项是英文。您将要忘记的事情将不那么明显(您多久测试一次西班牙语翻译?)。

于 2012-12-10T13:31:05.630 回答
3

你的活动被破坏,让你有机会重新配置自己以适应新的方向。

来自 developer.android.com:

当屏幕改变方向时,系统会销毁并重新创建前台 Activity,因为屏幕配置已更改并且您的 Activity 可能需要加载替代资源(例如布局)。

例如,在横向模式下,您可能需要完全不同的布局,或者可能希望加载不会出现拉伸的图形。这样做的最好方法是允许再次创建活动,这将允许链接到布局文件更改为对方向更友好的布局。

有关更多信息以及如何处理方向变化,请参阅http://developer.android.com/training/basics/activity-lifecycle/recreating.html

如果您想禁用娱乐,您可以添加

android:configChanges="orientation"

到 AndroidManifest.xml 中的 Activity 元素。这样您的 Activity 将不会被重新加载。

onSaveInstance并且onRestoreInstace应该只用于传递会话信息,例如 a 中的当前文本TextField,并且没有可以在 onCreate 之后再次加载的通用内容。

于 2012-11-30T15:18:24.917 回答
2

If you, restarting the Activity, requires recovering large sets of data, re-establishing a network connection, or perform other intensive operations then using the onSaveInstanceState() could potentially cause your noted symptoms:

  1. A poor user experience (i.e. "show some flickering")
  2. Require consumption of a lot of memory

onSaveInstanceState() callbacks are not designed to carry large objects.

To retain an object during a runtime configuration change:

Override the onRetainNonConfigurationInstance() method to return the object you would like to retain. When your activity is created again, call getLastNonConfigurationInstance() to recover your object.

However:

While you can return any object, you should never pass an object that is tied to the Activity, such as a Drawable, an Adapter, a View or any other object that's associated with a Context. If you do, it will leak all the views and resources of the original activity instance. (Leaking resources means that your application maintains a hold on them and they cannot be garbage-collected, so lots of memory can be lost.)

Source


Unless you are able to pass the Object(s) smoothly I personally think it is more advantageous to handle the configuration change yourself, meaning not to destroy.

If you have a target API of 13 or higher: You must include screenSize in your configChanges. Starting with API 13 the screen size also changes on orientation change and you'll need to account for this. Prior to 13 your Activity would handle this itself.

android:configChanges="orientation|screenSize"
于 2012-11-30T20:15:14.707 回答
0

有时,当您对(Landscape / Portrait)使用不同的布局时,它很有用。并使用不同类型的视图,例如ListView纵向和GridView横向。

于 2012-11-30T15:21:41.927 回答
0

我猜你没有考虑创建 android 布局的标准方式。如果我错了,请纠正我。您是否使用两个带有-port,-land的 res 文件夹分别告诉 android 系统在运行时选择根据方向加载不同的资产和布局。

示例可以为您提供管理不同方向的布局的线索。

这是 android标准文档。请检查“土地”和“港口”。

希望这会帮助你。

于 2012-12-10T13:30:59.137 回答