旋转Android时重新启动活动
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/456211/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Activity restart on rotation Android
提问by Isaac Waller
In my Android application, when I rotate the device (slide out the keyboard) then my Activity
is restarted (onCreate
is called). Now, this is probably how it's supposed to be, but I do a lot of initial setting up in the onCreate
method, so I need either:
在我的 Android 应用程序中,当我旋转设备(滑出键盘)时,我的设备Activity
会重新启动(onCreate
被调用)。现在,这可能是它应该的样子,但我在onCreate
方法中做了很多初始设置,所以我需要:
- Put all the initial setting up in another function so it's not all lost on device rotation or
- Make it so
onCreate
is not called again and the layout just adjusts or - Limit the app to just portrait so that
onCreate
is not called.
- 将所有初始设置放在另一个函数中,这样就不会在设备旋转或
- 使它
onCreate
不再被调用并且布局只是调整或 - 将应用程序限制为仅纵向,这样
onCreate
就不会被调用。
采纳答案by Reto Meier
Using the Application Class
使用应用程序类
Depending on what you're doing in your initialization you could consider creating a new class that extends Application
and moving your initialization code into an overridden onCreate
method within that class.
根据您在初始化中所做的事情,您可以考虑创建一个新类,该类Application
将您的初始化代码扩展并移动到onCreate
该类中的重写方法中。
public class MyApplicationClass extends Application {
@Override
public void onCreate() {
super.onCreate();
// TODO Put your application initialization code here.
}
}
The onCreate
in the application class is only called when the entire application is created, so the Activity restarts on orientation or keyboard visibility changes won't trigger it.
在onCreate
创建整个应用程序时在应用程序类只叫,等方向或键盘知名度转变活动重启不会触发它。
It's good practice to expose the instance of this class as a singleton and exposing the application variables you're initializing using getters and setters.
将此类的实例作为单例公开并公开使用 getter 和 setter 初始化的应用程序变量是一种很好的做法。
NOTE: You'll need to specify the name of your new Application class in the manifest for it to be registered and used:
注意:您需要在清单中指定新应用程序类的名称,以便注册和使用它:
<application
android:name="com.you.yourapp.MyApplicationClass"
Reacting to Configuration Changes[UPDATE: this is deprecated since API 13; see the recommended alternative]
对配置更改做出反应[更新:自 API 13 以来已弃用;查看推荐的替代方案]
As a further alternative, you can have your application listen for events that would cause a restart – like orientation and keyboard visibility changes – and handle them within your Activity.
作为进一步的选择,您可以让您的应用程序侦听会导致重新启动的事件(例如方向和键盘可见性更改),并在您的 Activity 中处理它们。
Start by adding the android:configChanges
node to your Activity's manifest node
首先将android:configChanges
节点添加到您的活动的清单节点
<activity android:name=".MyActivity"
android:configChanges="orientation|keyboardHidden"
android:label="@string/app_name">
or for Android 3.2 (API level 13) and newer:
或适用于Android 3.2(API 级别 13)及更新版本:
<activity android:name=".MyActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/app_name">
Then within the Activity override the onConfigurationChanged
method and call setContentView
to force the GUI layout to be re-done in the new orientation.
然后在 Activity 中覆盖该onConfigurationChanged
方法并调用setContentView
以强制在新方向上重新完成 GUI 布局。
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setContentView(R.layout.myLayout);
}
回答by Gorm
Update for Android 3.2 and higher:
Android 3.2 及更高版本的更新:
Caution: Beginning with Android 3.2 (API level 13), the "screen size" also changeswhen the device switches between portrait and landscape orientation. Thus, if you want to prevent runtime restarts due to orientation change when developing for API level 13 or higher (as declared by the minSdkVersion and targetSdkVersion attributes), you must include the
"screenSize"
value in addition to the"orientation"
value. That is, you must declareandroid:configChanges="orientation|screenSize"
. However, if your application targets API level 12 or lower, then your activity always handles this configuration change itself (this configuration change does not restart your activity, even when running on an Android 3.2 or higher device).
注意:从 Android 3.2(API 级别 13)开始,当设备在纵向和横向之间切换时,“屏幕尺寸”也会发生变化。因此,如果在为 API 级别 13 或更高级别(如 minSdkVersion 和 targetSdkVersion 属性所声明的)进行开发时,要防止由于方向更改而导致运行时重新启动
"screenSize"
,则除了该"orientation"
值之外,还必须包括该值。也就是说,您必须声明android:configChanges="orientation|screenSize"
. 但是,如果您的应用程序面向 API 级别 12 或更低级别,则您的 Activity 始终会自行处理此配置更改(此配置更改不会重新启动您的 Activity,即使在 Android 3.2 或更高版本的设备上运行时)。
回答by nebulae
Instead of trying to stop the onCreate()
from being fired altogether, maybe try checking the Bundle
savedInstanceState
being passed into the event to see if it is null or not.
与其试图完全阻止onCreate()
被触发,Bundle
savedInstanceState
不如尝试检查传递到事件中的事件以查看它是否为空。
For instance, if I have some logic that should be run when the Activity
is truly created, not on every orientation change, I only run that logic in the onCreate()
only if the savedInstanceState
is null.
例如,如果我有一些逻辑应该在Activity
真正创建时运行,而不是在每次方向更改时运行,我只onCreate()
在savedInstanceState
为空时才运行该逻辑。
Otherwise, I still want the layout to redraw properly for the orientation.
否则,我仍然希望布局为方向正确重绘。
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game_list);
if(savedInstanceState == null){
setupCloudMessaging();
}
}
not sure if this is the ultimate answer, but it works for me.
不确定这是否是最终答案,但它对我有用。
回答by Someone Somewhere
what I did...
我做了什么...
in the manifest, to the activity section, added:
在清单中,到活动部分,添加:
android:configChanges="keyboardHidden|orientation"
in the code for the activity, implemented:
在活动的代码中,实现了:
//used in onCreate() and onConfigurationChanged() to set up the UI elements
public void InitializeUI()
{
//get views from ID's
this.textViewHeaderMainMessage = (TextView) this.findViewById(R.id.TextViewHeaderMainMessage);
//etc... hook up click listeners, whatever you need from the Views
}
//Called when the activity is first created.
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
InitializeUI();
}
//this is called when the screen rotates.
// (onCreate is no longer called when screen rotates due to manifest, see: android:configChanges)
@Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
setContentView(R.layout.main);
InitializeUI();
}
回答by GregD
What you describe is the default behavior. You have to detect and handle these events yourself by adding:
您所描述的是默认行为。您必须通过添加以下内容来自己检测和处理这些事件:
android:configChanges
to your manifest and then the changes that you want to handle. So for orientation, you would use:
到您的清单,然后是您要处理的更改。因此,对于定位,您将使用:
android:configChanges="orientation"
and for the keyboard being opened or closed you would use:
对于打开或关闭的键盘,您将使用:
android:configChanges="keyboardHidden"
If you want to handle both you can just separate them with the pipe command like:
如果您想同时处理两者,您可以使用管道命令将它们分开,例如:
android:configChanges="keyboardHidden|orientation"
This will trigger the onConfigurationChanged method in whatever Activity you call. If you override the method you can pass in the new values.
这将在您调用的任何活动中触发 onConfigurationChanged 方法。如果覆盖该方法,则可以传入新值。
Hope this helps.
希望这可以帮助。
回答by Liudvikas Bukys
I just discovered this lore:
我刚刚发现了这个传说:
For keeping the Activity alive through an orientation change, and handling it through onConfigurationChanged
, the documentationand the code sample abovesuggest this in the Manifest file:
为了通过方向更改保持 Activity 活动并通过 处理它onConfigurationChanged
,上面的文档和代码示例在 Manifest 文件中建议了这一点:
<activity android:name=".MyActivity"
android:configChanges="orientation|keyboardHidden"
android:label="@string/app_name">
which has the extra benefit that it always works.
这有一个额外的好处,那就是它总是有效。
The bonus lore is that omitting the keyboardHidden
may seem logical, but it causes failures in the emulator (for Android 2.1 at least): specifying only orientation
will make the emulator call both OnCreate
and onConfigurationChanged
sometimes, and only OnCreate
other times.
奖金绝杀是省略keyboardHidden
似乎合乎逻辑,但它(至少为Android 2.1)导致的故障在模拟器:只有指定orientation
将使模拟器呼叫都OnCreate
和onConfigurationChanged
有时,只有OnCreate
其他时间。
I haven't seen the failure on a device, but I have heard about the emulator failing for others. So it's worth documenting.
我还没有在设备上看到失败,但我听说过其他人的模拟器失败。所以值得记录。
回答by Jon O
You might also consider using the Android platform's way of persisting data across orientation changes: onRetainNonConfigurationInstance()
and getLastNonConfigurationInstance()
.
您还可以考虑使用 Android 平台的跨方向更改持久化数据的方式: onRetainNonConfigurationInstance()
和getLastNonConfigurationInstance()
.
This allows you to persist data across configuration changes, such as information you may have gotten from a server fetch or something else that's been computed in onCreate
or since, while also allowing Android to re-layout your Activity
using the xml file for the orientation now in use.
这允许您跨配置更改保留数据,例如您可能从服务器获取的信息或在其中onCreate
或之后计算的其他内容,同时还允许 Android 重新布局您Activity
使用的方向的 xml 文件现在正在使用.
It should be noted that these methods are now deprecated (although still more flexible than handling orientation change yourself as most of the above solutions suggest) with the recommendation that everyone switch to Fragments
and instead use setRetainInstance(true)
on each Fragment
you want to retain.
应该注意的是,这些方法现在已被弃用(尽管仍然比上述大多数解决方案建议的那样自己处理方向更改更灵活),并建议每个人都切换到Fragments
并改为setRetainInstance(true)
在Fragment
您想要保留的每个上使用。
回答by Abdo
The approach is useful but is incomplete when using Fragments.
该方法很有用,但在使用 Fragments 时并不完整。
Fragments usually get recreated on configuration change. If you don't wish this to happen, use
片段通常会在配置更改时重新创建。如果您不希望发生这种情况,请使用
setRetainInstance(true);
in the Fragment's constructor(s)
setRetainInstance(true);
在片段的构造函数中
This will cause fragments to be retained during configuration change.
这将导致在配置更改期间保留片段。
http://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean)
http://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean)
回答by bass.t
I just simply added
我只是简单地添加了
android:configChanges="keyboard|keyboardHidden|orientation"
in the manifest file and did not addany onConfigurationChanged
method in my activity.
在清单文件中,并没有onConfigurationChanged
在我的活动中添加任何方法。
So every time the keyboard slides out or in nothing happens.
回答by ganesh krishnan
The onCreate
method is still called even when you change the orientation
of android. So moving all the heavy functionality to this method is not going to help you
onCreate
即使您更改了orientation
android的方法,该方法仍会被调用。因此,将所有繁重的功能转移到此方法对您没有帮助