По-перше, я знаю, що дійсно не слід вбивати / перезапускати додаток на Android. У моєму випадку використання я хочу відновити заводські налаштування своєї програми в конкретному випадку, коли сервер надсилає клієнту конкретну інформацію.
Користувач може увійти на сервер лише з одним екземпляром програми (тобто кілька пристроїв заборонено). Якщо інший екземпляр отримує цей "вхід" -блок, то всі інші екземпляри цього користувача повинні видалити свої дані (скинути заводські налаштування), щоб зберегти послідовність.
Блокування можна примусово отримати, оскільки користувач може видалити додаток та перевстановити його, що призведе до іншого ідентифікатора інстанції, і користувач більше не зможе звільнити замок. Тому замок можна насильно дістати.
Через таку силу сили нам потрібно завжди перевіряти в конкретному випадку, що він має замок. Це робиться на (майже) кожному запиті до сервера. Сервер може надіслати "неправильний код блокування". Якщо це виявлено, клієнтська програма повинна все видалити.
Це був випадок використання.
У мене є Activity
A, який запускає Activity
L або вхід у систему Activity
B, залежно від значення sharedPrefs. Після запуску L або B він закривається таким чином, що працює тільки L або B. Так що у випадку, якщо користувач увійшов у систему вже працює B.
B починає дзвонити C. C startService
для IntentService
D. Це результати в цьому стеку:
(A)> B> C> D
З методу onHandleIntent D подія надсилається ResultReceiver R.
R тепер обробляє цю подію, надаючи користувачеві діалогове вікно, де він може вибрати заводські скидання програми (видалити базу даних, sharedPrefs тощо)
Після скидання до заводських налаштувань я хочу перезапустити програму (закрити всі дії) і лише запустити A ще раз, який потім запустить логін Activity
L та завершить:
(A)> L
Метод onClick Dialog виглядає приблизно так:
@Override
public void onClick(DialogInterface dialog, int which) {
// Will call onCancelListener
MyApplication.factoryReset(); // (Deletes the database, clears sharedPrefs, etc.)
Intent i = new Intent(MyApp.getContext(), A.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MyApp.getContext().startActivity(i);
}
І ось MyApp
клас:
public class MyApp extends Application {
private static Context context;
@Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
}
public static Context getContext() {
return context;
}
public static void factoryReset() {
// ...
}
}
Проблема полягає в тому, якщо я використовую FLAG_ACTIVITY_NEW_TASK
Діяння B і C, як і раніше, виконуються. Якщо я натиснув кнопку "Назад" на вході, Activity
я побачу "C", але хочу повернутися на головний екран.
Якщо я не встановив, FLAG_ACTIVITY_NEW_TASK
я отримаю помилку:
07-07 12:27:12.272: ERROR/AndroidRuntime(9512): android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
Я не можу використовувати Діяльність ' Context
, оскільки ServiceIntent
D може бути викликаний також із фонового завдання, яке запускається AlarmManager
.
Тож як я міг вирішити це, щоб стек активності став (A)> L?