Во-первых, я знаю, что на самом деле нельзя убивать / перезапускать приложение на Android. В моем случае использования я хочу сбросить заводские настройки моего приложения в конкретном случае, когда сервер отправляет конкретную информацию клиенту.
Пользователь может войти на сервер только с ОДНОГО экземпляра приложения (т.е. несколько устройств не допускаются). Если другой экземпляр получает этот «вход в систему», тогда все остальные экземпляры этого пользователя должны удалить свои данные (сброс к заводским настройкам), чтобы сохранить согласованность.
Возможно принудительно получить блокировку, потому что пользователь может удалить приложение и переустановить его, что приведет к другому идентификатору экземпляра, и пользователь больше не сможет снять блокировку. Поэтому можно принудительно получить блокировку.
Из-за этой принудительной возможности нам нужно всегда проверять в конкретном случае, что он имеет блокировку. Это делается для (почти) каждого запроса к серверу. Сервер может отправить «неправильный идентификатор блокировки». Если это обнаружено, клиентское приложение должно удалить все.
Это был вариант использования.
У меня есть 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 теперь обрабатывает это событие, предоставляя пользователю диалоговое окно, в котором он может выбрать заводскую настройку приложения (удалить базу данных, sharedPrefs и т. Д.)
После сброса к заводским настройкам я хочу перезапустить приложение (чтобы закрыть все действия) и снова запустить только A, который затем запускает логин Activity
L и завершает себя:
(A)> L
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 все еще выполняются. Если я нажму кнопку «Назад» при входе в систему 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?