Перезавантажте активність в Android


221

Це хороша практика для перезавантаження Activityв Android ?

Який був би найкращий спосіб зробити це? this.finishа потім this.startActivityз діяльністю Intent?


3
Я не досвідчений розробник Android, але перезапуск діяльності виглядає як поганий дизайн, і це слід робити лише в крайніх випадках.
Гудсон

@Hudson Це відбувається при зміні конфігурації. Якщо це хороший дизайн чи ні, це цілком інша дискусія. ;)
hpique

1
@Hudson Отже, ви зараз 5 років досвіду розробника: D
Pratik Butani

@PratikButani, я тебе знаю? :) У мене зараз 8 років досвіду роботи, але не дуже багато в розробці Android.
Гудсон

Ви відвідали мій профіль Я знаю: P @Hudson
Pratik Butani

Відповіді:


521

Ви можете просто використовувати

finish();
startActivity(getIntent());

оновити Activityзсередини себе.


2
Що робити, якщо його не можна викликати всередині класу діяльності?
giorgiline

1
@giorgiline - Так, створіть інтерфейс, який ви визначаєте всередині класу діяльності, і передайте цей інтерфейс як параметр будь-якому зовнішньому класу, з якого ви його використовуєте.
агрегат1166877

1
Нічого собі, я не думав, що це буде просто.
theblang

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

1
@tothphu - Хоча не намагався, але теоретично я думаю, що так. Однак удруге, коли діяльність завершується, вона не поверне результат до створеної ним діяльності вперше.
Суш

65

для тих, хто не хоче бачити це моргання після методу відтворення (), просто використовуйте

 finish();
 overridePendingTransition(0, 0);
 startActivity(getIntent());
 overridePendingTransition(0, 0);

2
Дивовижно! Я хотів перекрити Перехід, щоб користувач не помітив!
Седі Мухоза

Чудова робота! Користувач ледве помітить перезавантаження.
сам

38

Це те, що я роблю, щоб перезавантажити діяльність після зміни повернення зі зміни уподобань.

@Override
protected void onResume() {

   super.onResume();
   this.onCreate(null);
}

Це по суті змушує діяльність перемальовуватися.

Оновлено: Кращий спосіб зробити це - викликати recreate()метод. Це призведе до відтворення діяльності.


15
Це може працювати, але настійно не рекомендується називати методи життєвого циклу чітко.
ITisha

Якщо ви скористаєтеся цим маршрутом, вам слід скористатися окремим методом init (), який встановлює все і викликає всередині onCreate () та onResume (), а не викликати onCreate ().
Том

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

1
Важливо враховувати запуск модуля діяльності при використанні відтворення (). Наприклад, коли я викликаю recreate () для діяльності з запусканнямMode = singleTop, я не бачу, щоб onCreate () викликався згодом. OTOH, якщо замість виклику відтворити () я явно викликаю закінчення (), а за ним - startActivity (), я бачу onCreate (), що викликається згодом.
albert c braun

14

Я бачив раніше відповіді, які були дані для перезавантаження діяльності за допомогою Intent. Вони працюватимуть, але ви можете зробити те ж саме, використовуючи метод відтворення (), наведений у самому класі активності.

Замість того, щоб писати це

// Оновити основну діяльність після закриття діалогового вікна

Intent refresh = new Intent(this, clsMainUIActivity.class);
startActivity(refresh);
this.finish();

Це можна зробити, лише написавши це

recreate();

recreate()було рішенням для мене - "перезапуск" активність не працювала для мене, оскільки я розпочав діяльність за допомогою "StartActivityForResult", і це порушило поведінку.
KYL3R


10

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

// Refresh main activity upon close of dialog box
Intent refresh = new Intent(this, clsMainUIActivity.class);
startActivity(refresh);
this.finish(); //

9

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

Хоча найкраща практика - це забезпечити, щоб ваші методи onPause та onStop звільнили будь-які ресурси, які вам не потрібно утримувати і використовувати onLowMemory для зменшення потреб у вашій діяльності до абсолютного мінімуму.


2
+1 для згадки про onLowMemory. Я не знав, що такий метод існує!
hpique

4

Почніть з вашої наміри activityі закрийте activity.

Intent refresh = new Intent(this, Main.class);
startActivity(refresh);//Start the same Activity
finish(); //finish Activity.

4

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

    Intent i = new Intent(myCurrentActivityName.this,activityIWishToRun.class);    
    startActivityForResult(i, GlobalDataStore.STATIC_INTEGER_VALUE);

річ полягає в тому, що коли ви закінчите () з діяльності IWishToRun, ви повернетесь до своєї життєвої діяльності


1
Це, можливо, старе, але ти просто врятував мені багато часу! :)
Lior Iluz

4

Перезавантажити всю свою діяльність може бути важким завданням. Просто поставте ту частину коду, яку потрібно оновити ( kotlin ):

override fun onResume() {
    super.onResume()
    //here...
}

Java:

@Override
public void onResume(){
    super.onResume();
    //here...

}

І телефонуйте " onResume () ", коли це потрібно.


2

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


Насправді я хочу змінити стан програми, а потім перезавантажити активність, щоб відобразити зміни.
hpique

Який "стан заявки" у вашому випадку? Переваги?
zehrer

2

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


Навпаки, я намагався "оновити" екран, перезапустивши активність. Itdoes не з’являється на поверхні нічого не пішло не так, моя інформація оновила те, як я хотів, LogCat розповідає іншу історію. У LogCat я повертаюся до методу onCreate діяльності, він намагається витягнути налаштування. Перша спроба я отримую виняток з нульовим вказівником, потім він знову намагається запуститись у onCreate і отримує зберігаєтьсяPref 2-й раз. Не впевнений, що тут відбувається, але я просто хотів бути впевненим, що ти не просто дивився на результат, бо WYSIWIG для мене не був таким.
taraloca

Як саме ви перезапускаєте діяльність?
hpique

2

У мене така ж проблема

import android.support.v4.content.IntentCompat;

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);

цей код працює для мене. Android api 17


2

У діяльності ви можете закликати recreate()"відтворити" діяльність (API 11+)


1

У мене був інший підхід на кшталт: якщо встановити launchModeсвою діяльність на singleTopта без дзвінків finish(), я просто startActivity(getIntent())зроблю цю роботу. Просто потрібно дбати про нові дані і в, onCreate()і вonNewIntent . За допомогою Суша програма може блимати так, як сказав АМАН СІНГ. Але підхід AMAN SINGH все одно створить нову діяльність, яка є якось непотрібною, навіть якщо він вирішив проблему "моргання", я думаю.

Надто пізно для цього питання, але якщо хтось шукає рішення, ось він.


0

Після входу у мене була та сама проблема, тому я і використовував

@Override
protected void onRestart() {
    this.recreate();
    super.onRestart();
}

0

Я використав це, і він відмінно працює без цього finish()

startActivity(getIntent());

0

для мене це працює, це не створювати ще одного Інтенту і на ті самі завантажені нові дані Intents.

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