Android життєвий цикл статичних об'єктів


101

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

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

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

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

Відповіді:


238

Почнемо з трохи тла: Що станеться при запуску програми?
ОС запускає процес і присвоює йому унікальний ідентифікатор процесу та виділяє таблицю процесів. Запуск процесу примірник DVM (Dalvik VM); Кожна програма працює всередині DVM.
DVM керує завантаженням завантаження класу, життєвим циклом екземпляра, GC тощо.

Термін служби статичної змінної: статична змінна виникає, коли клас завантажується JVM, і гине, коли клас завантажений.

Отже, якщо ви створите додаток для android та ініціалізуєте статичну змінну, він залишатиметься у JVM, поки не відбудеться одне з наступних випадків:
1. Клас не завантажується
2. JVM вимикається
3. процес гине

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

Ви можете перевірити це за допомогою кількох рядків коду:

  1. друкуйте неініціалізовану статику в onCreate своєї діяльності -> повинна надрукувати null
  2. ініціалізувати статику. надрукувати його -> значення було б недійсним
  3. Натисніть кнопку "назад" та перейдіть на головний екран. Примітка: Домашній екран - це ще одна діяльність.
  4. Почніть свою активність ще раз -> статична змінна буде ненулевою
  5. Вбийте процес подання заявки з DDMS (кнопка зупинки у вікні пристроїв).
  6. Перезапустіть свою діяльність -> статична матиме нульове значення.

Сподіваюся, що це допомагає.


1
Я хочу знати, чому я втрачаю значення поля в об’єкті програми, якщо воно не є статичним, коли я починаю нову діяльність, наприклад, я оголошую змінну поточну сторінку в об’єкті програми, і її значення завжди повертається до нуля, коли я відкриваю нову діяльність
Мохаммед Субхі Шейх Куроуш

коли я викликаю super.onRestoreInstanceState (збереженийInstanceState); Я втрачаю свою змінну, навіть якщо вони статичні, в чому проблема?
Мухаммед Субхі Шейх Куроуш

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

1
@suitianshi Я думаю, що ми можемо ініціалізувати статичні екземпляри в Application.onCreate, тому що навіть якщо наш додаток переходить у фоновий режим, і процес загине, як тільки ми повернемося до нашого додатка, клас додатків буде створений і викликає відповідні методи життєвого циклу знову! хоча мені потрібне підтвердження щодо цього, мені цікаво, чи може бути якийсь сценарій, коли статичний екземпляр, ініціалізований у Application.onCreate, втрачає своє значення?
Сартак Міттал

1
Що мені тут не вистачає, це пояснення для "1. клас вивантажений" - коли це станеться? Чи може JVM вивантажити клас, якщо у нього не вистачає пам'яті?
stoefln

16

Ну, шаблон Singleton також заснований на використанні статичних змінних, так що насправді ви знаходитесь в одному положенні. Хоча статичний підхід може працювати в більшості випадків, може траплятися, що в деяких випадках, коли пам'ять заповнена, а інша активність займає передній план, перш ніж ваша програма перейде на наступний екран, процес вашої діяльності може бути знищений, і ви втратите статичні значення. Однак Android пропонує кілька варіантів збереження значень між станами або передачі їх, таких як:

  • використовуючи Намір, ви можете передати свої критерії пошуку від активності до діяльності (подібно до веб-запиту http)
  • використовуючи налаштування програми, ви можете зберегти значення та отримати їх у тій діяльності, яка їм потрібна
  • за допомогою бази даних sqlite ви можете зберегти їх у таблиці та отримати їх пізніше
  • якщо вам потрібно просто зберегти стан активності, так що при перезапуску поля заповнюються попередньо вибраними значеннями, ви можете реалізувати метод активності onSaveInstanceState () - зауважте, що це не рекомендується для стійкості станів між діяльністю.

Ви можете отримати приклади коду використання налаштувань, намірів та бази даних sqlite, переглянувши дерево вихідного коду aegis-shield у коді Google або в інших програмах Android з відкритим кодом.


6

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

Не зберігайте дані в об’єкті програми

тому, хоча прийнята відповідь технічно правильна, вона не надає всієї інформації.

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


3

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

За документом Android: стан активності та викидання з пам'яті ,

Система ніколи не вбиває діяльність безпосередньо. Натомість він вбиває процес, в якому відбувається діяльність, знищуючи не тільки діяльність, але й все інше, що працює в процесі.

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

protected void onSaveInstanceState(Bundle state) {}
protected void onRestoreInstanceState(Bundle savedInstanceState){}

Отже, якщо у вас є клас, у якого є лише статичні змінні, ви можете зберегти стан кожного поля в onSaveInstanceState () та відновити їх у onRestoreInstanceState (). Коли Android вбиває процес, у якому працює ваша програма, стан ваших змінних буде збережено, а коли Android відновить ваш додаток, значення відновляться в пам'яті в тому ж стані, що і раніше.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.