Во-первых, я знаю, что на самом деле нельзя убивать/перезапускать приложение на Android. В моем случае я хочу factory - reset мое приложение в конкретном случае, когда сервер отправляет клиенту определенную информацию.
Пользователь может быть зарегистрирован на сервере только с ОДНОМ экземпляром приложения (т.е. несколько устройств не разрешены). Если другой экземпляр получает этот "logged-in" -lock, все остальные экземпляры этого пользователя должны удалить свои данные (factory - reset), чтобы поддерживать согласованность.
Можно принудительно получить блокировку, поскольку пользователь может удалить приложение и переустановить его, что приведет к другому идентификатору экземпляра, и пользователь больше не сможет освободить блокировку. Поэтому можно принудительно получить блокировку.
Из-за этой силовой возможности нам нужно всегда проверять конкретный пример, что он имеет блокировку. Это делается на (почти) каждом запросе на сервер. Сервер может послать "неверный-lock-id". Если это обнаружено, клиентское приложение должно удалить все.
Это был прецедент. Нет для вопроса реализации:
У меня есть Activity
A, который запускает Login 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 теперь обрабатывает это событие, предоставляя пользователю диалог, в котором он может выбрать factory - reset приложение (удалить базу данных, sharedPrefs и т.д.).
После factory - reset я хочу перезапустить приложение (чтобы закрыть все действия) и снова запустить A, который затем запускает login Activity
L и заканчивается:
(A) > L
Метод Dialog onClick выглядит следующим образом:
@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 все еще работают. Если я нажму кнопку "Назад" в login 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?