Почему бы не использовать всегда Android: configChanges = «клавиатура скрытая | ориентация»?

178

Мне было интересно, почему бы не использовать android:configChanges="keyboardHidden|orientation"в каждом (почти каждый;)) деятельность?

Товар:

  • не нужно беспокоиться о вашей активности
  • это быстрее

Не очень приятно

  • необходимо изменить макеты, если они зависят от размера экрана (например, макеты с двумя столбцами или около того)

Плохой:

  • нет гибкого способа иметь разные макеты с разной ориентацией
  • не очень хорошо при использовании фрагментов

Но если мы не используем разные макеты, почему бы и нет?

Mikooos
источник
6
Вы также должны объяснить, что, по вашему мнению, делает клавиатурно-скрытая ориентация
Бланделл,
Это не позволяет использовать собственную обработку указанных изменений конфигурации и позволяет приложению обрабатывать это, не так ли?
Mikooos
2
Вот почему эта опция есть, если вы знаете, что делаете (никаких изменений в ресурсах), используйте ее.
Указатель Нуль
почему это быстрее, чем с помощью ScreenSize?
Батмачи

Ответы:

334

Быстрый Фон

По умолчанию, когда в Android происходят определенные ключевые изменения конфигурации (типичным примером является изменение ориентации), Android полностью перезапускает запущенную активность, чтобы помочь ей приспособиться к таким изменениям.

Когда вы определяете android:configChanges="keyboardHidden|orientation"в своем AndroidManifest, вы говорите Android: «Пожалуйста, не делайте сброс по умолчанию, когда клавиатура извлечена или телефон повернут; я хочу справиться с этим самостоятельно. Да, я знаю, что делаю "

Это хорошо? Скоро увидим ...

Не беспокойся?

Одним из плюсов, с которого вы начинаете, является то, что есть:

не нужно беспокоиться о вашей активности

Во многих случаях люди ошибочно полагают, что, когда у них есть ошибка, которая генерируется изменением ориентации («поворот»), они могут просто исправить ее, вставив android:configChanges="keyboardHidden|orientation".

Тем не менее, android: configChanges = "клавиатура скрытая | ориентация" является ничем иным, как бинтом. По правде говоря, существует много способов изменения конфигурации. Например, если пользователь выбирает новый язык (т. Е. Языковой стандарт изменился), ваша деятельность будет возобновлена ​​так же, как при изменении ориентации. Если вы хотите, вы можете просмотреть список всех различных типов изменений конфигурации .

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

Другими словами, использование android:configChanges="keyboardHidden|orientation"не является решением для ваших "забот". Правильный путь - это кодировать ваши действия так, чтобы они были довольны любым перезапуском Android. Это хорошая практика, которая поможет вам в будущем, поэтому привыкните к ней.

Так, когда я должен использовать это?

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

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

Однако , если по какой-то причине вы используете другую компоновку, когда устройство находится в альбомной ориентации, тот факт, что Android перезагружает вашу активность, хорош, потому что тогда она загрузит правильную компоновку. [Если вы используете переопределение в таком Деятельности и хотите сделать магическое изменение макета во время выполнения ... ну, удачи - это далеко не просто]

Краткое резюме

Во что бы то ни стало, если вам android:configChanges="keyboardHidden|orientation"подходит, то используйте его. Но ПОЖАЛУЙСТА , обязательно проверьте, что происходит, когда что-то меняется, потому что изменение ориентации - не единственный способ полного перезапуска Действия.

yydl
источник
50
Стоит добавить, что отсутствие перезапуска вашей активности означает, что у вас есть большие проблемы, чем просто не менее частые изменения конфигурации. Используемый здесь перезапуск активности - это точно такой же механизм, как и то, как Android восстанавливает вашу активность в прежнем состоянии, когда ваше приложение убивается в фоновом режиме. Поэтому, если вы делаете это неправильно, ваши пользователи будут случайным образом возвращаться к вашему приложению, когда вернутся из него из фона, в зависимости от того, был ли процесс завершен. Так что огромное преимущество: оно гарантирует, что ваше приложение правильно перезагружается.
hackbod
14
Начиная с Android 3.x, добавляйте «screenSize» ---------- android: configChanges = [«mcc», «mnc», «locale», «touchscreen», «клавиатура», "клавиатура скрытая", "навигация", "screenLayout", "fontScale", "uiMode", "ориентация", "screenSize", "smalllestScreenSize"]
Майкл Бирманн
1
Я заметил, что когда вы используете атрибут configChanges, ваше приложение также игнорирует функцию ориентационной блокировки. Как вы можете решить это? если вы знаете ответ, пожалуйста, напишите его здесь: stackoverflow.com/questions/24000361/…
Android-разработчик
4
Please don't do the default reset when the keyboard is pulled outя никогда не видел перезапуска Activity для раскладки клавиатуры !
Мухаммед Бабар
ну, по моему мнению, случайные перезапуски в порядке ... configChanges обрабатывает большинство случаев для меня ... ну, может быть, в некоторых других типах приложений это может быть проблемой, но это действительно зависит ...
Renetik
2

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

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

Возьмем, к примеру, приложение, в котором у вас есть ListView, и после нажатия на ListItem вы хотите, чтобы вам было показано подробное представление для этого элемента. В альбомной ориентации это можно сделать, разделив экран на две части, имея ListView слева и подробный вид справа. В режиме «Портрет» список будет отображаться на одном экране, а затем будет изменен экран на подробный вид при выборе элемента ListItem. В этом случае изменение ориентации имеет смысл, а также различные макеты.

kaspermoerch
источник
4
Да, мы пошли с этим в версии 1.0 нашего приложения, чтобы соответствовать нашему выпуску Apple. Он был представлен ТОЛЬКО в портрете. Который выглядел великолепно на моем Droid X, мы точно соответствовали поведению всплывающей клавиатуры версии IOS. Затем финансовый директор установил приложение на своем Droid, повернул его в сторону и сдвинул клавиатуру. К сожалению. Особенность Android в том, что это открытая платформа, и вы действительно не можете предсказать аппаратную конфигурацию или то, что пользователь захочет с ней сделать, поэтому вам, вероятно, следует поддерживать обе (все) ориентации на всякий случай.
Tevo D
1
Это случайно нарушило нашу настройку только для портрета, поскольку в основном аппаратное обеспечение было тогда обычной, а не альтернативной ориентацией. Который ДЕЙСТВИТЕЛЬНО испортил наш макет :( и это было довольно неловко, так как через несколько секунд после установки приложения у него был большой недостаток
Tevo D
1
Почему вы пытались заставить его вести себя так же, как iOS? :(
FunkTheMonk
7
@FunkTheMonk К сожалению, мы живем в мире, где бизнесмены принимают технические решения. Даже если вы оспариваете это, они все равно считают, что они правы. И они контролируют вашу зарплату.
Переполнение стека
2
Использование только одного макета не означает, что при повороте экран будет выглядеть одинаково. Хорошо структурированная XML-разметка заставит вещи автоматически переключаться, чтобы работать в разумных пределах, и пользователи это оценят.
Мелинда Грин
-1

Я не понимаю, почему .... случайные перезапуски в порядке, на мой взгляд ... configChanges обрабатывает большинство случаев для меня ... ну, может быть, в некоторых типах приложений это может быть проблемой, но это действительно зависит от типа приложения и восстановления состояние, когда приложение перезапускается ... Когда одно из моих приложений перезагружается, пользователь снова входит в систему, и мой код открывает последнее действие, и пользователь jus теряет некоторые шаги, чтобы вернуться туда, где он был, но это не имеет большого значения. В других состояние всегда сохраняется и некоторое состояние всегда восстанавливается при перезапуске. Когда активность возобновилась, должно было случиться так, что приложение не использовалось или что-то ... так что никаких проблем вообще ... В игре, например, это может быть проблема, может быть, или в каком-то другом приложении, которое я не знаю ...

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

Так что убейте меня, но я использую это во всех приложениях довольно успешно ... android: configChanges = "locale | клавиатура | клавиатура скрытая | ориентация | screenLayout | uiMode | screenSize | smalllestScreenSize" Но я понимаю, что для некоторых специальных приложений это может быть не хороший способ, но большинство приложений могут жить с этим просто ОК.

Renetik
источник
Привет, может кто-то знающий в этой теме, пожалуйста, взгляните на мою ветку: stackoverflow.com/questions/35941585/…? Отчаянно нужна помощь.
Люк Эллисон
Вы должны полностью поддерживать сохранение / возобновление действий ... обработка для ротации ничем не отличается ... Вы говорите, что теряете несколько шагов ... если вы делаете это правильно, вы не теряете шагов и восстанавливаете именно там, где остановился пользователь ... даже после перезагрузки устройства.
HaMMeReD
Я не знаю, о чем вы говорите, но я говорю, что когда вы делаете это таким образом, приложения просто отлично работают в нормальных условиях. И код гораздо более читабелен без тонны логики, необходимой для сохранения и восстановления, где вы просто можете делать новые ошибки и постоянно поддерживать его ... уверен, что если Android выйдет из строя и убьет окно приложения, он потеряет контекст и начинается снова, но это происходит только в особых ситуациях и на новых устройствах я верю , это все более и более редкими ...
Renetik
Игнорирование условий договора о деятельности (сохранение / восстановление состояния) является плохой практикой, и это в целом ужасный совет. Попробуйте протестировать против смерти процесса и посмотрите, куда попадает ваше приложение, и это стандартное «нормальное обстоятельство», если ваш пользователь использует как минимум 2-3 приложения на своем телефоне и переключается между ними.
EpicPandaForce
-3

Да, я думаю, что пауза сделает это быстрее, чем освобождение игрока. Все еще есть пауза, хотя.

Теперь нашли решение, которое не остановит песню.

Укажите в манифесте, что вы будете обрабатывать изменение конфигурации для ориентации экрана, а затем используйте метод onConfigurationChanged для загрузки файла макета. Делая это в logCat, я вижу, что onPause, onCreate & onResume не вызываются, и поэтому песня не останавливается.

  1. обновить манифест для обработки ориентации.

    android:configChanges="orientation|screenSize"
  2. добавить этот код

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        // TODO Auto-generated method stub      
        super.onConfigurationChanged(newConfig);        
        setContentView(R.layout.activity_main);
    }
Raul
источник
Вы должны использовать сервис для воспроизведения музыки. Серьезно, вы говорите людям добавить код, в котором все еще есть "// TODO Auto-Generated заглушка метода". Небрежное решение. Это тоже не сработает, вам нужно перепривязать все ваши ссылки, и если вы этого не сделаете, они будут в лучшем случае непредсказуемыми.
HaMMeReD