强制Android在屏幕旋转时不重新绘制活动界面

3

我一直在努力弄清楚这个问题。
虽然我已经读了很多关于方向改变的文章,Android会杀死一个活动并作为新的重新开始,而唯一的处理方法是在onSaveInstanceState()中保存所有内容,并尝试在onCreate()内恢复它。

但我的活动在不同的时间进行着许多不同类型的网络活动,如果在执行网络活动时更改方向,则必须处理许多不同且复杂的情况。

是否有简单的方法只需指定Android在方向改变时不需要完全重绘此活动,以便自动保存所有数据并重复使用它?

我想知道是否有这样的东西。

8个回答

11
是的,你可以在AndroidManifest.xml文件中的活动声明中添加属性android:configChanges="orientation"
编辑: android:configChanges属性的目的是防止在必要时重新创建活动。例如,相机应用程序使用此属性,因为当方向更改时,相机预览屏幕不得重新创建。用户希望在旋转设备时相机预览能够在没有延迟的情况下工作,并且相机初始化不是非常快速的过程。因此,手动处理方向更改是相机应用程序的一种本地行为。
对于大多数应用程序而言,在方向更改期间是否重新创建活动并不重要。但是,有时由于活动创建缓慢、活动执行异步任务或其他原因,持久化活动可能更加方便。在这种情况下,可以微调应用程序并使用android:configChanges="orientation"属性。但是,在使用此调整时真正重要的是,您必须正确实现保存和还原状态的方法!
总之,android:configChanges可以使应用程序的性能得到改进,或在某些罕见情况下使其表现得“本地”,但它并不会减少您需要编写的代码量。

添加android:configChanges="orientation"可以解决问题,但是这篇博客 >http://www.gitshah.com/2011/03/how-to-handle-screen-orientation_28.html说这不是一个好的做法,可能会在以后引起麻烦。现在正在阅读更多相关内容。 - Aman Alam
1
我在那里找不到任何关于为什么这样做不好的解释。如果您只有一个布局文件用于活动,则我认为使用此方法是可以的。而且,我认为这是更改方向的活动最优化的方式,因为即使您使用onRetainNonConfigurationInstance(),活动重新创建肯定会更慢。 - Michael
1
@Pixie: "我在那里找不到任何解释为什么这是不好的。" -- 这是不好的,因为@Sheikh Aman将来会遭受严重的痛苦。随着这个改变,原始帖子(OP)将需要手动重新加载每一个由于配置更改而发生变化的资源。这将包括一些不明显如何手动重新加载的资源,例如维度资源。 - CommonsWare
我理解这一点,所以我说如果不需要根据活动方向更改布局,那么使用此方法是可以的。 - Michael
在原始问题中,“activity doesn't need to be redrawn” 意味着不需要更改其布局。 - Michael
显示剩余5条评论

6

但是我的应用程序在不同的时间进行了许多不同类型的网络活动,如果当网络活动正在执行时更改方向,我将不得不处理许多不同和复杂的情况。

然后将该逻辑移出活动并放入服务中。


没错。这可能是最好的方法,但可能需要更多的时间和精力。我一定会研究一下这个。谢谢马克! :) 又是一个对我非常有用的答案 :) - Aman Alam

4
是的,您可以在AndroidManifest.xml文件中的activity声明中添加属性android:configChanges="orientation"。
我认为最好声明android:configChanges="orientation|keyboard|keyboardHidden"。
关于您在其他答案中提供链接的博客文章。我想这里是答案:
如果您的应用程序不需要在特定配置更改期间更新资源,并且您有性能限制要求您避免Activity重启,则可以声明您的Activity自己处理配置更改,从而防止系统重新启动您的Activity。
我还与一位安卓开发者谈过这个问题。他的意思是,如果您没有横向和纵向方向的不同布局,您可以轻松使用configChanges。

2
我通过在清单文件的活动中添加以下内容解决了我的问题:
android:configChanges="keyboardHidden|orientation|screenSize"
该属性允许应用程序在屏幕方向或键盘可见性更改时保留其活动状态,而不是重新启动活动。

1

刚刚回答了这个问题:Android - screen orientation reloads activity

在您的情况下,您希望完全防止Android杀死您的Activity。 您需要更新您的清单以捕获方向更改,然后实现方向更改回调以在发生方向更改时实际执行您需要执行的任何操作(可能是无操作)。


是的,它可以工作,但这篇博客 -> http://www.gitshah.com/2011/03/how-to-handle-screen-orientation_28.html说这不是一个好的实践,可能会在以后造成麻烦。 - Aman Alam
如果您有逻辑将整个状态序列化为“Bundle”并在“onCreate”中从“Bundle”重建它(并且没有像网络或蓝牙连接这样的持久状态),那么我建议使用“onSaveInstanceState”。如果您有网络/蓝牙连接或类似的无法轻松重新创建的资源,则您的选择要么是不要像上面概述的那样杀死Activity,要么使用“onRetainNonConfigurationInstance()”。如果您使用第二个选项,则必须确保可以基于保留的对象将UI重建为正确的状态。您有多种选择。 - Femi

1
在 Manifest 文件中的 Activity 标签内加入 android:screenOrientation="portrait" 将会锁定你的屏幕方向。
更多信息请参考this link

我不想以任何方式锁定方向。 - Aman Alam

1
如果你在异步任务中进行了大量的网络操作,也许你应该使用onRetainNonConfigurationInstance()方法来保存数据,然后在onCreate()方法中获取数据,就像this tutorialthis所示。

第一段:这是一个关于编程的内容。编程是一种计算机语言,用于创建软件、应用程序和网站。它涉及到编写代码,以便计算机可以理解并执行指定的任务。编程语言有很多种,包括Java、Python、C++等。学习编程需要耐心和毅力,但它也是一项非常有用的技能,可以帮助你在职业生涯中取得成功。第二段:例如,下面是一个简单的Python代码示例:print("Hello, world!")这个程序将输出“Hello, world!”这个字符串。 - Amal

1
在清单文件中的活动中添加android:configChanges="orientation",并在活动类中添加以下代码进行检查。我希望这对您有所帮助。
@Override
public void onConfigurationChanged(Configuration newConfig)
    {
  super.onConfigurationChanged(newConfig);
  setContentView(R.layout.main);
}

当屏幕方向改变时,将调用此方法,除此之外不会有其他操作。如果您不想更改任何内容,请将其留空。


这只会让Android保持布局为main.xml吗?还是它也会防止重绘? - Aman Alam
我读了很多关于它的东西,到目前为止,看起来是一个不错的方法。谢谢! - Aman Alam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接