Как программно «перезапустить» приложение Android? - PullRequest
189 голосов
/ 07 июля 2011

Во-первых, я знаю, что на самом деле нельзя убивать / перезапускать приложение на 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?

Ответы [ 21 ]

0 голосов
/ 17 июля 2018

Вы можете возобновить текущую активность следующим образом:

Фрагмент:

activity?.recreate()

Активность:

recreate()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...