Как программно "перезапустить" приложение 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);
}