Чому б не використовувати завжди андроїд: configChanges = “клавіатураHidden | орієнтація”?


178

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

Товари:

  • не потрібно турбуватися про те, що ваша діяльність обертається
  • це швидше

Не так приємно:

  • потрібно змінити макети, якщо вони залежать від розміру екрана (наприклад, макети з двома стовпцями або так)

Погано:

  • немає гнучкого способу мати різні макети різної орієнтації
  • не так добре при використанні фрагментів

Але якщо ми не використовуємо різні макети, то чому б і ні?


6
Ви також повинні пояснити, що ви думаєте, що робить клавіатура прихованої | орієнтації
Блонделл

Це перешкоджає використанню власних технологій обробки зазначених змін конфігурації і дозволяє додатку обробляти це, чи не так?
Mikooos

2
Ось чому цей варіант є, якщо ви знаєте, що ви робите (без змін у ресурсах), використовуйте його.
Pointer Null

чому це швидше, ніж використання ScreenSize?
batmaci

Відповіді:


334

Швидкий фон

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

Коли ви визначаєте android:configChanges="keyboardHidden|orientation"у своєму AndroidManifest, ви говорите Android: "Будь ласка, не робіть скидання за замовчуванням, коли клавіатура виймається або телефон повертається; я хочу сам впоратися з цим. Так, я знаю, що я роблю "

Це гарна річ? Незабаром ми побачимо ...

Не хвилюйтесь?

Одним із плюсів, з якого ви починаєте, є те, що є:

не потрібно турбуватися про те, що ваша діяльність обертається

У багатьох випадках люди помилково вважають, що коли у них виникає помилка, яка створюється зміною орієнтації ("обертання"), вони можуть її просто виправити, ввівши android:configChanges="keyboardHidden|orientation".

Однак android: configChanges = "keyboardHidden | орієнтація" - це не що інше, як bandaid. По правді, існує багато способів зміни конфігурації. Наприклад, якщо користувач вибирає нову мову (тобто змінено локаль), ваша активність буде відновлена ​​так само, як це відбувається шляхом зміни орієнтації. Якщо потрібно, ви можете переглянути список різних типів змін конфігурації .

Редагувати : Що ще важливіше, проте, як в коментарях зазначає хакбод , ваша активність також буде відновлена, коли ваша програма буде у фоновому режимі, і Android вирішить звільнити деяку пам’ять, убивши її. Коли користувач повернеться до вашої програми, Android спробує перезапустити діяльність так само, як це робиться, якщо відбулася якась інша зміна конфігурації. Якщо ви не можете впоратися з цим - користувач не буде задоволений ...

Іншими словами, використання android:configChanges="keyboardHidden|orientation"не є рішенням для ваших «турбот». Правильний спосіб - це кодувати свою діяльність, щоб вони були задоволені будь-яким перезавантаженням кидків Android. Це хороша практика, яка допоможе вам в дорозі, тому звикайте.

То коли я повинен його використовувати?

Як ви вже згадували, є явна перевага. Перезапис зміни конфігурації за замовчуванням для обертання, обробляючи його самостійно, прискорить роботу. Однак ця швидкість дійсно має ціну зручності.

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

Однак якщо ви з якоїсь причини використовуєте інший макет, коли пристрій знаходиться в ландшафтному режимі, той факт, що Android перезавантажує вашу активність, добре, оскільки він завантажить правильний макет. [Якщо ви використовуєте переопрацювання для такої діяльності та хочете зробити якийсь магічний перепланування під час виконання ... ну, удача - це далеко не просто]

Швидкий підсумок

У будь-якому випадку, якщо android:configChanges="keyboardHidden|orientation"вам підходить, тоді використовуйте його. Але ЗАБУДУЮТЬСЯ , щоб перевірити, що відбувається, коли щось змінюється, оскільки зміна орієнтації - не єдиний спосіб повного перезапуску активності.


50
Варто додати, що неперевірка роботи з вашою діяльністю означає, що у вас є більші проблеми, ніж просто не обробляти менш поширені зміни конфігурації. Використовуваний тут перезапуск діяльності - це точно такий же механізм, як і відновлення діяльності Android до попереднього стану, коли ваша програма загине у фоновому режимі. Тож якщо ви цього не робите правильно, ваші користувачі відчують, що ваш додаток не випадково повертається належним чином, коли вони повертаються до нього з фону, залежно від того, чи трапився процес вбиття. Тож величезна користь: вона гарантує, що ваш додаток правильно перезавантажиться.
hackbod

14
З Android 3.x не пропустіть додавання "screenSize" ---------- android: configChanges = ["mcc", "mnc", "locale", "сенсорний екран", "клавіатура", "клавіатура прихована", "навігація", "екранна розкладка", "шрифт шрифту", "uiMode", "орієнтація", "розмір екрана", "найменший розмір екрана"]
Майкл Бірманн

1
Я помітив, що коли ви використовуєте атрибут configChanges, ваш додаток також ігнорує функцію блокування орієнтації. Як ви можете це вирішити? якщо ви знаєте відповідь, напишіть її тут: stackoverflow.com/questions/24000361/…
андроїд розробник

4
Please don't do the default reset when the keyboard is pulled outя ніколи не бачив перезавантаження діяльності для виведення клавіатури !
Мухаммед Бабар

ну, випадкові перезавантаження, на мій погляд, нормально ... configChanges обробляє більшість випадків для мене ... ну, можливо, в деяких інших типах додатків це може бути проблемою, але це залежить насправді ....
Renetik

2

З моєї точки зору: Якщо макет однаковий і в пейзажному, і в портретному режимі - ви також можете відключити один із двох у вашому додатку.

Причина, чому я заявляю про це, полягає в тому, що я, як користувач, очікує, що додаток надасть мені певну користь під час зміни орієнтації. Якщо не важливо, як я тримаю телефон, то мені вибір не потрібен.

Візьмемо, наприклад, додаток, де у вас є ListView, і натиснувши на ListItem, ви хочете, щоб він відобразив детальний вигляд цього елемента. У ландшафті ви б це зробили, розділивши екран на два, маючи ListView зліва та детальний вигляд справа. У "Портрет" ви будете мати список на одному екрані, а потім змінити екран на детальний вигляд, коли вибрано ListItem. У цьому випадку зміна орієнтації має сенс, а також різні схеми.


4
Так, ми працювали у версії 1.0 нашого додатка, щоб відповідати нашій версії Apple. Він був представлений ТІЛЬКИ в портреті. Що чудово виглядало на моєму Droid X, ми точно відповідали поведінці клавіатури, що з’являється у версії IOS. Тоді фінансовий директор встановив додаток на свій Droid, повернув його вбік і відкрив клавіатуру. На жаль Справа в Android полягає в тому, що це відкрита платформа, і ви дійсно не можете передбачити конфігурацію обладнання або що користувач захоче зробити з цим, тому вам, мабуть, слід підтримувати обидві (всі) орієнтації на всякий випадок.
Тево Д

1
Що, до речі, перевершило наші налаштування лише для портретів, оскільки в основному в апаратному забезпеченні пейзаж був тоді нормальною, а не почерговою орієнтацією. Який дійсно зіпсував наш макет :( і був досить неприємний, маючи головний недолік протягом декількох секунд після його встановлення програми
Tevo D

1
Чому ви намагалися змусити його вести себе точно як iOS? :(
FunkTheMonk

7
@FunkTheMonk На жаль, ми живемо у світі, де бізнесмени приймають технічні рішення. Навіть якщо ви сперечаєтесь проти цього, половину часу вони вважають, що так чи інакше. І вони контролюють вашу зарплату.
StackOverflowed

2
Використання лише одного макета не означає, що екран буде виглядати однаково при повороті. Добре структурований макет XML призведе до того, що речі автоматично зміняться, щоб добре працювати з розумними розмірами, і користувачі це оцінять.
Мелінда Грін

-1

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

Я кажу, що коли ви це робите, додатки просто працюють нормально за звичайних обставин. А код набагато легше читати без тон логіки, необхідної для збереження та відновлення, де ви просто можете робити нові помилки і постійно підтримувати його ... впевнений, що якщо android вийде з-під влади і вб'є вам вікно програми, він втратить контекст і починається знову, але це трапляється просто в особливих ситуаціях, і на нових пристроях я вірю, що це все рідше і рідше ...

Так що вбийте мене, але я використовую це в додатках досить успішно ... android: configChanges = "locale | клавіатура | клавіатураHidden | орієнтація | screenLayout | uiMode | screenSize | najmanjiScreenSize", але я розумію, що для деяких спеціальних програм це може бути не Хороший спосіб, але більшість програм може жити з цим просто ОК.


Привіт, може хтось знаючий на цю тему, будь ласка, подивіться на мою тему: 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);
    }

Ви повинні використовувати послугу для відтворення музики. Серйозно, ви говорите людям додати код, у якому все ще є "// TODO Автоматично створений заглушок методу". Неохайне рішення. Це також не буде добре працювати, вам потрібно буде відновити всі свої посилання, і якщо цього не зробити, вони в кращому випадку будуть непередбачуваними.
HaMMeReD
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.