当前位置:  开发笔记 > 编程语言 > 正文

在Android上旋转活动重启

如何解决《在Android上旋转活动重启》经验,为你挑选了23个好方法。

在我的Android应用程序中,当我旋转设备(滑出键盘)然后我Activity重新启动(onCreate被调用).现在,这可能是它应该如何,但我在onCreate方法中做了很多初始设置,所以我需要:

    将所有初始设置放在另一个功能中,这样就不会在设备旋转时丢失所有功能

    这样做onCreate不会再次调用,布局只是调整或

    将应用限制为仅限肖像,以便onCreate不调用.

Reto Meier.. 949

使用应用程序类

根据您在初始化时所做的操作,您可以考虑创建一个新类,该类Application将初始化代码扩展并移动到onCreate该类中的重写方法中.

public class MyApplicationClass extends Application {
  @Override
  public void onCreate() {
    super.onCreate();
    // TODO Put your application initialization code here.
  }
}

onCreate创建整个应用程序时在应用程序类只调用,所以活动的方向或键盘能见度变化重启不会触发它.

最好将此类的实例公开为单例,并使用getter和setter公开正在初始化的应用程序变量.

注意:您需要在清单中指定新Application类的名称,以便注册和使用它:



对配置更改做出反应 [更新:自API 13以来不推荐使用此功能; 看推荐替代 ]

作为另一种选择,您可以让应用程序侦听可能导致重新启动的事件(如方向和键盘可见性更改),并在您的Activity中处理它们.

首先将android:configChanges节点添加到Activity的清单节点

 

或Android 3.2(API级别13)及更新版本:


然后在Activity中覆盖onConfigurationChanged方法并调用setContentView以强制GUI布局在新方向中重新完成.

@Override
public void onConfigurationChanged(Configuration newConfig) {
  super.onConfigurationChanged(newConfig);
  setContentView(R.layout.myLayout);
}

这里希望我们将来能看到一个onRotate()方法.甚至担心这样的事情 - 坦率地说是令人沮丧的. (225认同)

请注意[Android开发指南](http://developer.android.com/guide/topics/manifest/activity-element.html#config)警告不要使用此:**注意:使用(`android:configChanges`)应避免使用,仅作为最后手段使用.请阅读处理运行时更改以获取有关如何正确处理由于配置更改而导致重新启动的更多信息.**为了代替,为了在旋转事件中保留数据,他们似乎更喜欢使用`onSaveInstanceState Bundle`; 或者作为@ Jon-O [提及](http://stackoverflow.com/a/7509094/260559),`onRetainNonConfigurationInstance`. (82认同)

这是一个糟糕的解决方案,因为它只对当前已知的配置更改做出反应.对于较新的Android版本,可能会发生此代码无法捕获的其他配置更改(因为它必须列出清单中的所有配置更改).使用`onRetainNonConfigurationChanges`保存状态的解决方案更具容错性和直接性. (18认同)

我不认为第二种方法有效.我尝试过这个; 一个带有EditText的Activity.我在那里写了一些文字,改变方向,文字消失/重置. (16认同)

我认为你应该在[3.2](http://stackoverflow.com/a/9550231/503900)上添加[此更新]给你的答案,这非常重要(只是遇到了这个问题),它可能会被忽视. (14认同)

使用`android:configChanges`为我节省了大量的工作,所以我讨厌谷歌告诉我只使用它作为最后的手段而不解释*为什么*.给我一个不节省大量工作的理由.请. (6认同)

不要忘记`android:configChanges`中的`keyboardHidden`.我做了,它导致活动被破坏并重建. (2认同)

Google表示不使用`android:configChanges`,因为:_自行配置更改可能会使使用其他资源变得更加困难,因为系统不会自动为您应用它们[来源](http://developer.android. com/guide/topics/resources/runtime-changes.html#HandlingTheChange)使用它来防止纵向/横向似乎是合理的,因为你说你根本不想处理它.警告:我是android n00b. (2认同)


Gorm.. 183

Android 3.2及更高版本的更新:

注意:从Android 3.2(API级别13)开始,当设备在纵向和横向之间切换时,"屏幕大小"也会更改.因此,如果要在开发API级别13或更高级别(由minSdkVersion和targetSdkVersion属性声明)时由于方向更改而阻止运行时重新启动,则必须在"screenSize"值之外包含该"orientation"值.也就是说,你必须申报android:configChanges="orientation|screenSize".但是,如果您的应用程序的目标是API级别12或更低,那么您的活动始终会自行处理此配置更改(即使在Android 3.2或更高版本的设备上运行,此配置更改也不会重新启动您的活动).

添加android:configChanges**应该只用作最后的手段**.考虑使用`Fragments`和`setRetainInstance`代替. (4认同)


nebulae.. 123

onCreate()可以尝试检查Bundle savedInstanceState传入事件以查看它是否为空,而不是试图完全阻止被解雇.

例如,如果我有一些逻辑应该在Activity真正创建时运行,而不是在每次方向更改时运行,我只在onCreate()savedInstanceState值为null 时才运行该逻辑.

否则,我仍然希望布局正确地重新绘制方向.

public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_game_list);

        if(savedInstanceState == null){
            setupCloudMessaging();
        }
}

不确定这是否是最终的答案,但它对我有用.



1> Reto Meier..:

使用应用程序类

根据您在初始化时所做的操作,您可以考虑创建一个新类,该类Application将初始化代码扩展并移动到onCreate该类中的重写方法中.

public class MyApplicationClass extends Application {
  @Override
  public void onCreate() {
    super.onCreate();
    // TODO Put your application initialization code here.
  }
}

onCreate创建整个应用程序时在应用程序类只调用,所以活动的方向或键盘能见度变化重启不会触发它.

最好将此类的实例公开为单例,并使用getter和setter公开正在初始化的应用程序变量.

注意:您需要在清单中指定新Application类的名称,以便注册和使用它:



对配置更改做出反应 [更新:自API 13以来不推荐使用此功能; 看推荐替代 ]

作为另一种选择,您可以让应用程序侦听可能导致重新启动的事件(如方向和键盘可见性更改),并在您的Activity中处理它们.

首先将android:configChanges节点添加到Activity的清单节点

 

或Android 3.2(API级别13)及更新版本:


然后在Activity中覆盖onConfigurationChanged方法并调用setContentView以强制GUI布局在新方向中重新完成.

@Override
public void onConfigurationChanged(Configuration newConfig) {
  super.onConfigurationChanged(newConfig);
  setContentView(R.layout.myLayout);
}


这里希望我们将来能看到一个onRotate()方法.甚至担心这样的事情 - 坦率地说是令人沮丧的.
请注意[Android开发指南](http://developer.android.com/guide/topics/manifest/activity-element.html#config)警告不要使用此:**注意:使用(`android:configChanges`)应避免使用,仅作为最后手段使用.请阅读处理运行时更改以获取有关如何正确处理由于配置更改而导致重新启动的更多信息.**为了代替,为了在旋转事件中保留数据,他们似乎更喜欢使用`onSaveInstanceState Bundle`; 或者作为@ Jon-O [提及](http://stackoverflow.com/a/7509094/260559),`onRetainNonConfigurationInstance`.
这是一个糟糕的解决方案,因为它只对当前已知的配置更改做出反应.对于较新的Android版本,可能会发生此代码无法捕获的其他配置更改(因为它必须列出清单中的所有配置更改).使用`onRetainNonConfigurationChanges`保存状态的解决方案更具容错性和直接性.
我不认为第二种方法有效.我尝试过这个; 一个带有EditText的Activity.我在那里写了一些文字,改变方向,文字消失/重置.
我认为你应该在[3.2](http://stackoverflow.com/a/9550231/503900)上添加[此更新]给你的答案,这非常重要(只是遇到了这个问题),它可能会被忽视.
使用`android:configChanges`为我节省了大量的工作,所以我讨厌谷歌告诉我只使用它作为最后的手段而不解释*为什么*.给我一个不节省大量工作的理由.请.
不要忘记`android:configChanges`中的`keyboardHidden`.我做了,它导致活动被破坏并重建.
Google表示不使用`android:configChanges`,因为:_自行配置更改可能会使使用其他资源变得更加困难,因为系统不会自动为您应用它们[来源](http://developer.android. com/guide/topics/resources/runtime-changes.html#HandlingTheChange)使用它来防止纵向/横向似乎是合理的,因为你说你根本不想处理它.警告:我是android n00b.

2> Gorm..:

Android 3.2及更高版本的更新:

注意:从Android 3.2(API级别13)开始,当设备在纵向和横向之间切换时,"屏幕大小"也会更改.因此,如果要在开发API级别13或更高级别(由minSdkVersion和targetSdkVersion属性声明)时由于方向更改而阻止运行时重新启动,则必须在"screenSize"值之外包含该"orientation"值.也就是说,你必须申报android:configChanges="orientation|screenSize".但是,如果您的应用程序的目标是API级别12或更低,那么您的活动始终会自行处理此配置更改(即使在Android 3.2或更高版本的设备上运行,此配置更改也不会重新启动您的活动).


添加android:configChanges**应该只用作最后的手段**.考虑使用`Fragments`和`setRetainInstance`代替.

3> nebulae..:

onCreate()可以尝试检查Bundle savedInstanceState传入事件以查看它是否为空,而不是试图完全阻止被解雇.

例如,如果我有一些逻辑应该在Activity真正创建时运行,而不是在每次方向更改时运行,我只在onCreate()savedInstanceState值为null 时才运行该逻辑.

否则,我仍然希望布局正确地重新绘制方向.

public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_game_list);

        if(savedInstanceState == null){
            setupCloudMessaging();
        }
}

不确定这是否是最终的答案,但它对我有用.


你在哪里实际上拯救国家?
这似乎对我有用,它似乎是迄今为止最简单的方法.我注意到你只有4个up(5个包括我的)而373个关于子类化Application的想法,这对我来说似乎要复杂得多.这个方法有什么缺点吗?
这个解决方案对我来说很有用.我能够`Intent serverintent = new Intent(MainActivity.this,MessageListener.class);`和`startService(serverintent);`创建`serverSocket = new ServerSocket(0xcff2);`和`Socket client = serverSocket.accept ();`使用`BufferedReader(new InputStreamReader(client.getInputStream()));`并且可以旋转我的android并保持客户端/服务器连接处于活动状态,但是GUI旋转.根据手册,savedInstanceState在最后一个活动关闭时被初始化.
我不明白,有什么收获?这种方法效果很好,并且复杂程度远低于其他任何解决方案.
这是在Android中执行此操作的正确方法.基本上使用configChanges捕获旋转的其他方法以及所有笨重,复杂和不必要的方法.

4> Someone Some..:

我做了什么...

在清单中,到活动部分,添加:

android:configChanges="keyboardHidden|orientation"

在活动的代码中,实现了:

//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();
}


请记住,我的答案就像是3岁,Android不断发展......西蒙 - 你有一个示例代码的链接吗?这就是人们的需要.
澄清:通过我的实现,您现在可以在onCreate()中进行变量初始化,并且只需调用onConfigurationChanged()进行屏幕旋转.你的变量现在与屏幕旋转绝缘;-) nice和ez
当对android:configChanges发出警告时,@SimonAndréForsberg实际上只是在解释[Android docs](http://developer.android.com/guide/topics/manifest/activity-element.html#config).[处理运行时更改](http://developer.android.com/guide/topics/resources/runtime-changes.html)提供了有关替代方案的更详细信息(包括示例代码).

5> GregD..:

您描述的是默认行为.您必须通过添加以下内容来自行检测和处理这些事件:

android:configChanges

到您的清单,然后是您想要处理的更改.因此,对于方向,您将使用:

android:configChanges="orientation"

并且对于打开或关闭的键盘,您将使用:

android:configChanges="keyboardHidden"

如果你想要处理两者,你可以使用管道命令将它们分开,如:

android:configChanges="keyboardHidden|orientation"

这将在您调用的任何Activity中触发onConfigurationChanged方法.如果覆盖该方法,则可以传入新值.

希望这可以帮助.


@GregD我知道,这就是为什么现在是个更新它以反映当今情况的好时机。鉴于这个问题的支持人数众多,SO上的其他问题仍在引用它。

6> Liudvikas Bu..:

我刚刚发现了这个传说:

为了使Activity通过方向更改保持活动并进行处理onConfigurationChanged,上面的文档和代码示例在Manifest文件中提示:


它具有始终有效的额外好处.

奖金传说是省略keyboardHidden可能看起来合乎逻辑,但它会导致模拟器失败(至少对于Android 2.1):仅指定orientation将使模拟器同时调用OnCreate,onConfigurationChanged有时只调用OnCreate其他时间.

我没有看到设备上的故障,但我听说过仿真器失败了.所以值得记录.


注意:从Android 3.2(API级别13)开始,当设备在纵向和横向之间切换时,"屏幕大小"也会更改.因此,如果您希望在开发API级别13或更高级别时因为方向更改而阻止运行时重新启动:android:configChanges ="orientation | keyboardHidden | screenSize"

7> Jon O..:

您也可以考虑使用Android平台在方向更改中保持数据的方式: onRetainNonConfigurationInstance()getLastNonConfigurationInstance().

这允许您在配置更改中保留数据,例如您可能从服务器提取中获取的信息或在其中onCreate或之后计算的其他信息,同时还允许Android Activity使用xml文件重新布局您正在使用的方向.

看这里或这里.

应该注意的是,这些方法现在已被弃用(尽管仍然比上述大多数解决方案所建议的更方便地处理方向更改),建议每个人切换到您想要保留的每个方法Fragments,而不是使用setRetainInstance(true)它们Fragment.


我真的认为Fragments和setRetainInstance是这样做的最佳方式(以及谷歌推荐的方式),+1给你,-1给所有其他人.添加android:configChanges**应仅用作最后的手段**

8> Abdo..:

该方法很有用,但在使用Fragments时不完整.

通常会在配置更改时重新创建片段.如果您不希望发生这种情况,请使用

setRetainInstance(true); 在Fragment的构造函数中

这将导致在配置更改期间保留片段.

http://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean)


同意.使用最新的Android API,似乎片段是处理此问题的正确方法.我自己还没有尝试过,但是从我收集的内容[本页](https://developer.android.com/guide/components/fragments.html)中,您基本上可以移动99%的使用量在Activity中实现Fragment的子类,然后将Fragment添加到Activity中.该活动仍将被销毁并在屏幕旋转时重新创建,但您可以使用提及的'setRetainInstance()方法@Abdo专门告诉android _not_来销毁Fragment.

9> 小智..:

我只是简单地说

     android:configChanges="keyboard|keyboardHidden|orientation"

在清单文件中并没有onConfigurationChanged在我的活动中添加任何方法.

所以每次键盘滑出或没有任何反应.



10> 小智..:

onCreate即使您更改了orientationandroid,该方法仍然会被调用.因此,将所有重要功能移至此方法并不会对您有所帮助



11> Carol..:
 onConfigurationChanged is called when the screen rotates. 
 (onCreate is no longer called when screen rotates due to manifest, see:  
 android:configChanges)

清单的哪一部分告诉它"不要打电话onCreate()"?

此外,谷歌的文档说,以避免使用android:configChanges(除非作为最后的手段)....但随后他们建议所有DO使用的替代方法android:configChanges.

根据我的经验,模拟器总是要求onCreate()轮换.
但是我运行相同代码的1-2个设备却没有.(不确定为什么会有任何区别.)



12> Vaishali Sut..:

将以下代码放入您的代码中Manifest.xml:

android:configChanges="screenLayout|screenSize|orientation"



13> ManiTeja..:

只需执行以下步骤即可:



这对我有用:

注意:方向取决于您的要求



14> sumit pandey..:

Android清单中的更改包括:

android:configChanges="keyboardHidden|orientation" 

内部活动的增加是:

public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
    }
}



15> Parin Parikh..:

将此行添加到清单中: -

android:configChanges="orientation|keyboard|keyboardHidden|screenSize|screenLayout|uiMode"

和活动的这个片段: -

@Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
    }



16> Piyush..:

做这件事有很多种方法:

保存活动状态

您可以保存活动状态onSaveInstanceState.

@Override
public void onSaveInstanceState(Bundle outState) {
    /*Save your data to be restored here
    Example : outState.putLong("time_state", time); , time is a long variable*/
    super.onSaveInstanceState(outState);
}

然后使用bundle恢复状态.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if(savedInstanceState!= null){
       /*When rotation occurs
        Example : time = savedInstanceState.getLong("time_state", 0); */
    } else {
      //When onCreate is called for the first time
    }
}

处理方向变化自己

另一种方法是自己处理方向变化.但这不是一个好习惯.

将其添加到清单文件中.

android:configChanges="keyboardHidden|orientation"

适用于Android 3.2及更高版本:

android:configChanges="keyboardHidden|orientation|screenSize"

@Override
public void onConfigurationChanged(Configuration config) {
    super.onConfigurationChanged(config);

if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        //Handle rotation from landscape to portarit mode here
    } else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE){
        //Handle rotation from portrait to landscape mode here
    }
}

限制旋转

您还可以将活动限制为纵向或横向模式以避免旋转.

将其添加到清单文件中的activity标记:

        android:screenOrientation="portrait"

或者在您的活动中以编程方式实现:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}



17> Carl..:

即使它不是"Android方式",我通过自己处理方向更改并简单地在视图中重新定位小部件以考虑更改的方向,获得了非常好的结果.这比任何其他方法都快,因为您的视图不必保存和恢复.它还为用户提供了更加无缝的体验,因为重新定位的小部件是完全相同的小部件,只是移动和/或调整大小.不仅可以以这种方式保存模型状态,还可以保存视图状态.

RelativeLayout对于必须不时重新定位的视图,有时可能是一个不错的选择.您只需为每个子窗口小部件提供一组纵向布局参数和一组景观布局参数,每个参数都有不同的相对定位规则.然后,在您的onConfigurationChanged()方法中,将适当的一个传递setLayoutParams()给每个孩子的调用.如果任何子控件本身需要在内部重新定向,您只需在该子项上调用一个方法来执行重定向.那个孩子同样呼吁任何方法需要重新定位内部,等子控件.



18> Shaun..:

我发现这样做的方法是使用onRestoreInstanceStateonSaveInstanceState事件来保存一些东西Bundle(即使你不需要保存任何变量,只是把东西放在那里,所以Bundle不是空的).然后,在该onCreate方法上,检查是否Bundle为空,如果是,则进行初始化,如果不是,则执行此操作.



19> Mansuu......:

每次旋转屏幕时,打开的活动都会完成,并再次调用onCreate().

1.当屏幕旋转时,你可以做一件事保存活动状态,这样,当再次调用活动的onCreate()时,你可以恢复所有旧东西.请参阅此 链接

2.如果要阻止重新启动活动,请在manifest.xml文件中放置以下行.

  



20> iHank..:

注意:如果将来某人遇到与我相同的问题,我会发布此答案.对我来说,没有采用以下方法:

android:configChanges="orientation"

当我旋转屏幕时,方法`onConfigurationChanged(Configuration newConfig)没有被调用.

解决方案:即使问题与方向有关,我也必须添加"screenSize".所以在AndroidManifest.xml文件中,添加:

android:configChanges="keyboardHidden|orientation|screenSize"

然后实现该方法 onConfigurationChanged(Configuration newConfig)



21> koteswara D ..:

您需要使用onSavedInstanceState方法将所有值存储到其参数中,即has是bundle

@Override
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
        super.onSaveInstanceState(outState, outPersistentState);
        outPersistentState.putBoolean("key",value);
    }

并使用

@Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        savedInstanceState.getBoolean("key");
    } 

要检索并查看对象,它将处理屏幕旋转



22> 小智..:

在活动部分manifest,添加:

android:configChanges="keyboardHidden|orientation"



23> 小智..:

在清单中添加以下行: android:configChanges="orientation|screenSize"

推荐阅读
N个小灰流_701
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有