Как программно "перезапустить" приложение Android?

Во-первых, я знаю, что не нужно действительно убивать / перезапускать приложение на Android. В моем случае использования я хочу сбросить заводские настройки моего приложения в конкретном случае, когда сервер отправляет конкретную информацию клиенту.

Пользователь может быть авторизован на сервере только с ОДНЫМ экземпляром приложения (т.е. несколько устройств не допускаются). Если другой экземпляр получает этот "вход в систему", тогда все остальные экземпляры этого пользователя должны удалить свои данные (сброс к заводским настройкам), чтобы сохранить согласованность.

Можно принудительно получить блокировку, потому что пользователь может удалить приложение и переустановить его, что приведет к другому идентификатору экземпляра, и пользователь больше не сможет снять блокировку. Поэтому можно принудительно получить блокировку.

Из-за этой форсированной возможности мы должны всегда проверять в конкретном случае, что он имеет блокировку. Это делается для (почти) каждого запроса к серверу. Сервер может отправить "неправильный идентификатор блокировки". Если это обнаружено, клиентское приложение должно удалить все.


Это был вариант использования. Нет для реализации-вопрос:

у меня есть Activity А, который запускает Логин 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 Л и заканчивает себя:

(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?

35 ответов

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

Фрагмент:

activity?.recreate()

Деятельность:

recreate()

С помощью библиотеки Process Phoenix. Действие, которое вы хотите перезапустить, называется "А".

Аромат Java

// Java
public void restart(){
    ProcessPhoenix.triggerRebirth(context);
}

Котлин аромат

// kotlin
fun restart() {
    ProcessPhoenix.triggerRebirth(context)
}

Альтернативный ответ Микепенза в моем случае потребовал некоторых изменений. /questions/10049676/kak-programmno-perezapustit-prilozhenie-android/10049699#10049699 Основные заслуги в ответе Mikepenz, который я мог бы изменить.

Вот статическая функция Plug and Play, которая у меня сработала.

Просто передайте контекст приложения, и эта функция выполнит перезапуск.

          public static void doRestart(Context c) {
        try {
            // check if the context is given
            if (c != null) {
                // fetch the package manager so we can get the default launch activity
                // (you can replace this intent with any other activity if you want
                PackageManager pm = c.getPackageManager();
                // check if we got the PackageManager
                if (pm != null) {
                    // create the intent with the default start activity for your application
                    Intent mStartActivity = pm.getLaunchIntentForPackage(c.getPackageName());
                    if (mStartActivity != null) {
                        mStartActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                        
                        c.getApplicationContext().startActivity(mStartActivity);
                        // kill the application
                        System.exit(0);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            Log.e("restart", "Could not Restart");
        }
    }

эй, братан, если вы хотите перезапустить свое приложение одним нажатием кнопки, напишите этот код и не забудьте изменить сброс с именем вашей кнопки, и если вы запустите это во фрагменте, это не сработает, потому что я выбрал javascript, а он это язык Java

В MainActivity вызовите метод restartActivity:

public static void restartActivity(Activity mActivity) {
    Intent mIntent = mActivity.getIntent();
    mActivity.finish();
    mActivity.startActivity(mIntent);
}
Другие вопросы по тегам