Вопрос: Перезагрузка активности при ротации Android


В моем приложении для Android, когда я поворачиваю устройство (выдвигаю клавиатуру), тогда мой Activityперезапускается ( onCreateназывается). Теперь это, вероятно, так, как это должно быть, но я делаю много первоначальной настройки в onCreateметод, поэтому мне нужно:

  1. Поместите всю начальную настройку в другую функцию, чтобы она не была полностью потеряна при вращении устройства или
  2. Сделай это так onCreateснова не вызывается, а макет просто настраивается или
  3. Ограничьте приложение только портретом, чтобы onCreateне называется.

1210


источник


Ответы:


Использование класса приложения

В зависимости от того, что вы делаете при инициализации, вы можете рассмотреть возможность создания нового класса, который расширяется Applicationи перемещение вашего кода инициализации в переопределенную onCreateметод внутри этого класса.

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

onCreateв классе приложения вызывается только при создании всего приложения, поэтому активность перезапуска при изменении ориентации или изменения видимости клавиатуры не вызовет его.

Эффективная практика заключается в том, чтобы разоблачить экземпляр этого класса как одноэлементный и подвергнуть переменные приложения, которые вы инициализируете, используя геттеры и сеттеры.

ПРИМЕЧАНИЕ. Вам нужно будет указать имя нового класса приложения в манифесте для его регистрации и использования:

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

Реагирование на изменения конфигурации [ОБНОВЛЕНИЕ: это устарело, поскольку API 13; см. рекомендуемую альтернативу ]

В качестве дополнительной альтернативы вы можете заставить приложение прослушивать события, которые приведут к изменениям, связанным с перезапуском - как ориентация и видимость клавиатуры, - и обрабатывать их в рамках вашей деятельности.

Начните с добавления android:configChangesузла к узлу манифеста вашего действия

android:configChanges="keyboardHidden|orientation"

или для Android 3.2 (API-уровень 13) и новее :

android:configChanges="keyboardHidden|orientation|screenSize"

Затем в пределах Действия переопределяют onConfigurationChangedметод и вызов setContentViewчтобы заставить графический интерфейс пользователя быть переделанным в новой ориентации.

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

890



Обновление для Android 3.2 и выше:

предосторожность : Начиная с Android 3.2 (уровень API 13), «размер экрана» также изменяется когда устройство переключается между портретной и альбомной ориентацией. Таким образом, если вы хотите предотвратить перезапуск во время перезагрузки из-за изменения ориентации при разработке для уровня API 13 или выше (как указано атрибутами minSdkVersion и targetSdkVersion), вы должны включить "screenSize"в дополнение к "orientation"стоимость. То есть, вы должны объявить android:configChanges="orientation|screenSize", Однако, если ваше приложение нацелено на уровень API 12 или ниже, ваша деятельность всегда обрабатывает это изменение самой конфигурации (это изменение конфигурации не перезапускает вашу активность даже при работе на устройстве Android 3.2 или выше).


173



Вместо того, чтобы пытаться остановить onCreate()от увольнения вообще, возможно, попробуйте проверить Bundle savedInstanceStateпередается в событие, чтобы узнать, является ли оно нулевым или нет.

Например, если у меня есть некоторая логика, которая должна выполняться, когда Activityдействительно создается, а не при каждом изменении ориентации, я только запускаю эту логику в onCreate()только если savedInstanceStateнулевой.

В противном случае, я все еще хочу, чтобы макет правильно перерисовывал ориентацию.

public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_game_list);

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

не уверен, что это окончательный ответ, но он работает для меня.


109



что я сделал...

в манифесте, в раздел активности, добавлено:

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

93



То, что вы описываете, - это поведение по умолчанию. Вы должны сами определять и обрабатывать эти события, добавляя:

android:configChanges

к вашему манифесту, а затем изменения, которые вы хотите обработать. Поэтому для ориентации вы будете использовать:

android:configChanges="orientation"

и для открывания или закрывания клавиатуры вы будете использовать:

android:configChanges="keyboardHidden"

Если вы хотите обрабатывать оба, вы можете просто отделить их от команды pipe, например:

android:configChanges="keyboardHidden|orientation"

Это вызовет метод onConfigurationChanged во всех действиях, которые вы вызываете. Если вы переопределите метод, который вы можете передать в новых значениях.

Надеюсь это поможет.


57



Я только что открыл эти знания:

Для сохранения активности через изменение ориентации и ее обработку onConfigurationChanged, документация а также пример кода выше предположите это в файле манифеста:

android:configChanges="keyboardHidden|orientation"

который имеет дополнительную выгоду, что он всегда работает.

Бонус - это то, что keyboardHiddenможет показаться логичным, но это вызывает сбои в эмуляторе (по крайней мере, для Android 2.1): указание только orientationвызовет эмулятор OnCreateа также onConfigurationChangedиногда и только OnCreateв других случаях.

Я не видел сбоя на устройстве, но я слышал об отсутствии эмулятора для других. Поэтому стоит документировать.


39



You might also consider using the Android platform's way of persisting data across orientation changes: onRetainNonConfigurationInstance() and 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.

See here or here.

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.


33



The approach is useful but is incomplete when using 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)

This will cause fragments to be retained during configuration change.

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


28



I just simply added

     android:configChanges="keyboard|keyboardHidden|orientation"

in the manifest file and did not add any onConfigurationChanged method in my activity.

So every time the keyboard slides out or in nothing happens.


21