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


117

Привіт, мені цікаво, як Android керує пам'яттю, і я не можу ніде знайти точну відповідь. Припустимо, у мене є додаток із 5 видами діяльності на поточному стеку активності (4 зупинено і 1 відновлено), сервіс не підключений. Я натискаю кнопку ДОМАШНИЙ, щоб всі мої дії були припинені. Я запускаю деякі інші програми, що споживають пам'ять, і загальна пам’ять пристрою починає бути низькою. І питання в цьому

... Що буде з моєю заявою?

  1. Чи може система знищити лише одну чи деякі мої дії для відновлення пам'яті?
  2. Чи знищить систему весь процес моєї заявки? Чи всі дії будуть добре знищені?
  3. Що буде, коли я повернуся до своєї заяви, коли вона була повністю вбита? Почнеться з початківців (як перший старт) чи спробує відновити діяльність до попереднього стану / якщо так - це лише той, що знаходиться на вершині стека, або всі вони?

ОНОВЛЕННЯ:

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

Я не перевіряв відповідь на запитання 1, але, як говорить керівництво:

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

Здається, що одну або кілька заходів можна обережно знищити (методом onDestroy), не вбиваючи процес. Ви просто отримаєте (onCreate + пакет), коли повернетесь до них.

Відповідь на питання 2:

ТАК. Зазвичай система вбиває весь процес, це означає, що всі дані, включаючи діяльність та статичні поля, знищуються. Це НЕ робиться красиво - ви не отримаєте onDestroy або штрафуєте () за будь-яку з призупинених / зупинених дій. Ось чому saveInstanceState () викликається безпосередньо перед методом onPause. onPause - це в основному останній метод, де вам слід щось зберегти, оскільки після цього методу ви ніколи не могли бачити onStop або onDestroy. Система може просто знищити процес знищення всіх ваших об'єктів, що б вони не мали, і що б вони не робили.

Відповідь на питання 3:

Що станеться, коли ви повернетесь до вбитої програми?

  • До Android 2.2 - додаток почнеться з початківців, починаючи з запуску.
  • Починаючи з 2.2 - система відновить попередній стан програми. Що це означає? Це означає, що остання видима активність буде відтворена (onCreate + bundle). Що буде з стеком активності? Стек чудово, але всі дії на ньому мертві. Кожен з них буде відтворений (onCreate + пакет), коли ви повернетесь до нього за допомогою кнопки "назад". Є ще одне в цьому:

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

Висновок?

  1. Не думайте, що проблеми з обертанням операцій обертання можна вирішити за допомогою android: configChanges = "орієнтація". Коли ви це зробите, у вас виникне багато інших проблем, про які ви навіть не знаєте.
  2. Перевірте свою програму за допомогою DDMS - кнопка "Зупинити процес". Дивіться це
  3. Будьте уважні при використанні статичних змінних. Не думайте, що коли ви ініціалізуєте їх у діяльності 1 - ви будете їх ініціалізувати у діяльності 2. Єдиним безпечним місцем для ініціалізації глобальної статики буде клас додатків.
  4. Пам'ятайте, що ви ніколи не бачите onStop або onDestroy. Закрийте файли / бази, зупиніть завантажувачі в програмі Pauuse. Якщо ви хочете, щоб програма щось робила в БГ - використовуйте сервіс переднього плану.

Це було б ... Сподіваюся, я допоміг зі своєю ессі :)


Як ви вважаєте, чи є ці 5 видів діяльності з одного додатка чи декількох різних додатків?
гантелі

1
"У мене є додаток з 5 видами діяльності на поточному стеку активності" Звичайно, вони всі з моєї, однієї і тієї ж заявки на процес.
Марк

4
Дякую, це було саме моє запитання ... Ваше запитання та відповіді мені дуже допомогли.
craigrs84


@Mark: Чи вирішена ця проблема зараз? Як якщо це?
Ameer Moaaviah

Відповіді:


30

Спочатку подивіться на це:

img1

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

onStop () Викликається, коли діяльність більше не відображається користувачеві, оскільки інша діяльність відновлена ​​і охоплює цю. Це може статися або тому, що запускається нова діяльність, перед цим приводиться існуюча, або ця знищується. Після цього або onRestart (), якщо ця активність повертається для взаємодії з користувачем, або onDestroy (), якщо ця діяльність припиняється.

Отже, коли ви натискаєте кнопку "ДОМАШНЯ" на вашому пристрої, ваша поточна активність переднього плану буде надіслана onPause()потім onStop(), інші 4 повинні залишитисяonStop()

Згідно з документами Google:

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

І, для життєвого циклу процесу:

Життєвий цикл процесу 3. Фонова активність (діяльність, яку не видно користувачеві і була призупинена), вже не є критичною, тому система може безпечно знищити процес, щоб відновити пам'ять для інших переднього плану або видимих ​​процесів. Якщо його процес потрібно знищити, коли користувач повернеться до активності (зробивши його знову видимим на екрані), його метод onCreate (Bundle) буде викликаний з збереженим ранішеInstanceState, який він раніше постачав у OnSaveInstanceState (Bundle), щоб він може перезапустити себе в тому ж стані, коли останній раз його залишив користувач.

Усі наведені вище пропозиції походять від: Довідник для розробників Android: Діяльність

Підтверджено, що система може знищити недіяльні дії та переробити пам'ять під час запуску деяких програм, що споживають пам'ять. І ви можете реалізувати на зразок: isFinishing()у своїй діяльності, а потім за допомогою кнопки "вбити" в DDMS, щоб виявити, яку з ваших дій відкидає система. Але я здогадуюсь, система спочатку знищить найдавнішу. Однак не має сенсу зберігати інші види діяльності, коли "Запуск активності" був перероблений.

ОНОВЛЕННЯ

Ось декілька думок, які я знайшов звідси :

Зупинений стан

Коли діяльність не видно, але все ще в пам’яті, ми говоримо, що вона перебуває у зупиненому стані. Зупинене заняття можна повернути на фронт, щоб знову стати Запущеним заняттям. Або його можна було знищити та вилучити з пам'яті.

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

Зупинені дії можна видалити з пам'яті в будь-який момент.


4
Документація з цього приводу є досить заплутаною, проте може бути забитий лише цілий процес, а не окремі компоненти (діяльність, послуги тощо). Див: stackoverflow.com/questions/7536988 / ...
greg7gkb

Це питання має бути оновлено інформацією за посиланням на коментар @ greg7gkb, його оману
Лука Де Фео

1

Чи може система знищити лише одну чи деякі мої дії для відновлення пам'яті?

Так. Android вбиває дії, які виконуються у фоновому режимі, коли є необхідність у пам’яті. Вбивство одного або всіх може залежати від деяких умов. Наприклад, призупинений або зупинений примірник може змусити Android вбити активність або сам процес. Тут, у розділі " Життєвий цикл" діяльності, ви можете отримати бали нижче. Я рекомендую вам повністю пройти цю сторінку. Це однозначно очистить ваші сумніви.

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

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

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


Чи знищить систему весь процес моєї заявки? Чи всі дії будуть добре знищені?

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


Що буде, коли я повернуся до своєї заяви, коли вона була повністю вбита?

Це схоже на перезапуск. Знову третій пункт дасть вам відповіді на кшталтWhen it is displayed again to the user, it must be completely restarted and restored to its previous state

Дізнайтеся більше про інформацію, пов’язану з пам'яттю, тут .

Редагувати:
усі дії в додатку виконуються в одному процесі. Тож, коли процес буде вбито, усі дії, незалежно від 5 чи 10, будуть вбиті, тобто, перезапущені. Перезапуск призведе до того, що ваша програма запускається спочатку без збережених станів.


2
Я бачив життєвий цикл діяльності щонайменше 5 разів, але це не відповідає на мої запитання. Те, що ви сказали, означало б, коли мій процес додавання буде вбитий - коли я повернусь до програми, він відновиться до попереднього стану. Отже, коли у мене було 5 припинених дій. Чи всі вони померли (на "Дестрой"), коли процес був убитий? Коли я повернувся до свого додатка, чи були відновлені всі дії (onCreate + bundle) чи лише одна у верхній частині стеку (видно користувачеві)?
Марк

1
Усі дії в додатку виконуються в одному процесі. Тож, коли процес буде вбито, усі дії, незалежно від 5 чи 10, будуть вбиті, тобто, перезапущені. Перезапуск призведе до того, що ваша програма запускатиметься спочатку без збережених станів ..
Vinay

1
Майже правда, але не для 2.2 і вище. Дивіться моє оновлення вгорі сторінки.
Марк

1
Ні, це неправда і ніколи не було правдою. Це оману засноване на документації, але дивіться: stackoverflow.com/questions/7536988 / ...
greg7gkb

2
@JJPA Android не може знищити одиночну діяльність для відновлення пам'яті, вона лише знищує процеси. Дивіться цю відповідь Діанна Хакбор, член основної команди Android, що бере участь у впровадженні "вбивці пам'яті": stackoverflow.com/a/7576275/1290264 .
bcorso
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.