在 Android 轮播上重新启动活动

在我的 Android 应用程序中,当我旋转设备(滑出键盘)时,我的Activity将重新启动(调用onCreate )。现在,这大概应该是这样,但是我在onCreate方法中做了很多初始设置,所以我需要:

  1. 将所有初始设置都放在另一个功能中,这样就不会因设备旋转或
  2. 使其不再被onCreate再次调用,布局只是调整或
  3. 将应用程序限制为仅纵向模式,以便不调用onCreate

答案

使用应用程序类

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

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

仅在创建整个应用程序时才调用应用程序类中的onCreate ,因此 Activity 在方向上重新启动,否则键盘可见性更改不会触发它。

优良作法是将此类的实例公开为单例,并使用 getter 和 setter 公开要初始化的应用程序变量。

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

<application
    android:name="com.you.yourapp.MyApplicationClass"

对配置更改做出反应 [更新:自 API 13 起不推荐使用; 请参阅推荐的替代方法 ]

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

首先将android:configChanges节点添加到 “活动” 的清单节点中

<activity android:name=".MyActivity"
      android:configChanges="orientation|keyboardHidden"
      android:label="@string/app_name">

或适用于Android 3.2(API 级别 13)及更高版本

<activity android:name=".MyActivity"
      android:configChanges="keyboardHidden|orientation|screenSize"
      android:label="@string/app_name">

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

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

Android 3.2 及更高版本的更新:

注意 :从 Android 3.2(API 级别 13)开始,当设备在纵向和横向之间切换时, “屏幕尺寸” 也会更改 。因此,如果要防止在为 API 级别 13 或更高级别开发时(由于 minSdkVersion 和 targetSdkVersion 属性所声明的)方向改变而导致运行时重启,则除了"orientation"值外,还必须包括"screenSize" "orientation"值。也就是说,您必须声明android:configChanges="orientation|screenSize" 。但是,如果您的应用程序以 API 级别 12 或更低级别为目标,则您的活动始终会自行处理此配置更改(即使在 Android 3.2 或更高版本的设备上运行,此配置更改也不会重新启动您的活动)。

与其尝试完全停止触发onCreate()savedInstanceState尝试检查将Bundle savedInstanceState传递到事件中以查看其是否为 null。

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

否则,我仍然希望布局重新绘制以适应方向。

public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_game_list);

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

不知道这是否是最终答案,但这对我有用。

我做了什么...

在清单中的 “活动” 部分中添加:

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

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

android:configChanges

到清单,然后更改要处理的内容。因此,对于定向,您将使用:

android:configChanges="orientation"

对于打开或关闭的键盘,您可以使用:

android:configChanges="keyboardHidden"

如果要同时处理这两种情况,则可以使用管道命令将它们分开,例如:

android:configChanges="keyboardHidden|orientation"

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

希望这可以帮助。

我刚刚发现了这个传说:

为了通过方向更改使活动保持活动状态,并通过onConfigurationChanged对其进行onConfigurationChanged上述文档代码示例在清单文件中提出了建议:

<activity android:name=".MyActivity"
      android:configChanges="orientation|keyboardHidden"
      android:label="@string/app_name">

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

额外的知识是,省略keyboardHidden似乎是合乎逻辑的,但它会导致模拟器失败(至少对于 Android 2.1):仅指定orientation会使模拟器有时同时调用OnCreateonConfigurationChanged ,而仅调用OnCreate其他时间。

我还没有看到设备上的故障,但是我听说模拟器对其他设备失败。因此,值得记录。

您可能还会考虑使用 Android 平台的跨方向更改持久化数据的方式: onRetainNonConfigurationInstance()getLastNonConfigurationInstance()

这样一来,您就可以在配置更改期间保留数据,例如您可能是从服务器获取的信息或在onCreate或之后获得的其他信息中保留的,同时还允许 Android 现在使用 xml 文件重新定向Activity的方向正在使用。

看到这里这里

应该注意的是,现在不建议使用这些方法(尽管比上面大多数解决方案所建议的处理方向更改要灵活得多),建议所有人都切换到Fragments ,而对要保留的每个Fragment使用setRetainInstance(true)

该方法很有用,但在使用片段时不完整。

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

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

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

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

我只是简单地添加

android:configChanges="keyboard|keyboardHidden|orientation"

在清单文件中,并且在我的活动中添加任何onConfigurationChanged方法。

因此,每次键盘滑出或滑入都不会发生

即使您更改 android 的orientationonCreate方法仍然会被调用。因此,将所有繁重的功能移至此方法都无济于事