Жизненный цикл деятельности-onCreate призвал к каждой переориентации


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

После поворота 2 раза я получаю FC, потому что для растрового изображения может быть выделено недостаточно памяти. (Все ли экземпляры activty еще где-то живы? Или все-таки ГК не убирать быстро достаточно?)

@Override
public void onCreate(Bundle savedInstanceState) {
    File externalStorageDir = Environment.getExternalStorageDirectory();
    File picturesDir = new File(externalStorageDir, "DCIM/Camera");
    File[] files = picturesDir.listFiles(new FilenameFilter(){
        public boolean accept(File dir, String name) {
            return name.toLowerCase().endsWith(".jpg");
        }});
    if (files.length > 0) {
        Bitmap bm = BitmapFactory.decodeStream(new FileInputStream(files[0]));
        ImageView view = (ImageView) findViewById(R.id.photo);
        view.setImageBitmap(bm);
    }
}

Из всего, что я читал, onCreate должен быть вызван один раз в течение жизни приложения. Неужели я ошибаюсь? Как переориентация устройства может привести к воссозданию действия?

12 46

12 ответов:

Действие по умолчанию воссоздается после каждого поворота. Вы можете переопределить это поведение с помощью атрибута configChanges тега activity в AndroidManifest. Дополнительные сведения и различные варианты см. В разделе http://developer.android.com/guide/topics/resources/runtime-changes.html

android:configChanges="keyboardHidden|orientation|screenSize"

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

Http://developer.android.com/guide/topics/resources/runtime-changes.html

Что происходит, когда ориентация меняется

Жизненный цикл ориентации

onPause();
onSaveInstanceState();
onStop();
onDestroy();

onCreate();
onStart();
onResume();

---- приложение воссоздано и теперь работает - - -

Если вы выполняете длительную операцию в onCreate() и хотите предотвратить повторное создание своей активности, добавьте атрибут configChanges в свой mainfest

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

ScreenSize Если вы нацелены на api >= 13

Если вы хотите предотвратить нехватку памяти в FC, вам нужно освободить ресурсы в onStop() или onPause(). это позволяет использовать свежую память в onCreate().

Это альтернативное решение для предотвращения возобновления деятельности с помощью

android:configChanges="keyboardHidden|orientation"

Как иногда макет вашей деятельности отличается в портрете и ландшафте (макет, макет-земля). предотвращение повторного создания при изменении ориентации не позволит вашей деятельности использовать макет другой ориентации.

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

//Define Below in you Manifest file.
           <activity
                  android:name="com.ecordia.activities.evidence.MediaAttachmentView"
                  android:configChanges="keyboardHidden|orientation|screenSize"
            </activity>

//Define Below in your activity. 

         @Override
            public void onConfigurationChanged(Configuration newConfig) {

              super.onConfigurationChanged(newConfig);

              if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
                  //your code
              } else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
            //your code

              }
            }

Это будет работать как заклинание!!

Да, activity onCreate() вызывается каждый раз, когда orientation изменяется, но вы можете избежать re-creation из Activity, добавив configChanges attribute из Activity в свой AndroidManifest файл в теге activity.

android:configChanges="keyboardHidden|orientation"

Жизненный цикл Actvity при повороте экрана

onPause
onSaveInstanceState
onStop
onDestroy

onCreate
onStart
onRestoreInstanceState
onResume

Использовать

android:configChanges="keyboardHidden|orientation" in Manifest XML activity Tag

@Override
public void onConfigurationChanged(Configuration newConfig) {
    // TODO Auto-generated method stub
    super.onConfigurationChanged(newConfig);
}

Используйте приведенный выше код для выполнения изменений, связанных с ориентацией в вашей деятельности Java-код

Ура!!!

Одним из наиболее распространенных и предлагаемых "решений" проблемы изменения ориентации является отказ от нее. Вы можете сделать это, установив флаг android:configChanges на вашей активности в AndroidManifest.xml, как показано ниже:

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

Это неправильный способ борьбы с изменениями ориентации.

Правильный способ-реализовать метод onSaveInstanceState (это может быть в вашей активности, фрагменте или обоих) и поместить значения, которые вам нужно сохранить, в аргумент Bundle, который передается методу.

Это прекрасно описано здесь: http://code.hootsuite.com/orientation-changes-on-android/

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

Пожалуйста, посмотрите, как я это делаю: -

Http://animeshrivastava.blogspot.in/2017/08/activity-lifecycle-oncreate-beating_3.html

Фрагмент: -

@Override
    protected void onSaveInstanceState(Bundle b)
    {
            super.onSaveInstanceState(b);
        String str="Screen Change="+String.valueOf(screenChange)+"....";
            Toast.makeText(ctx,str+"You are changing orientation...",Toast.LENGTH_SHORT).show();
        screenChange=true;

    }

    @Override
    public void onCreate(Bundle b)
        {
        super.onCreate(b);
        ctx=getApplicationContext();
        if(!screenChange)
        {
             String str="Screen Change="+String.valueOf(screenChange);

У меня была та же проблема, в которой мой onCreate вызывается несколько раз при изменении ориентации экрана. Моя проблема была решена, когда я добавил android:configChanges="orientation|keyboardHidden|screenSize" в тег activity в manifest

У меня была та же проблема, и я сделал некоторый обходной путь

Определить логическую переменную didLoad со значением false

Private boolean didLoad = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity);

    if (!this.didLoad){
        // Your code...
        this.didLoad = true;
    }