Жизненный цикл деятельности-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 ответов:
Действие по умолчанию воссоздается после каждого поворота. Вы можете переопределить это поведение с помощью атрибута
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; }