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

231

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

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

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

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


Это был вариант использования.

У меня есть ActivityA, который запускает Login ActivityL или основной ActivityB приложения в зависимости от значения sharedPrefs. После запуска L или B он закрывается, так что работает только L или B. Таким образом, в случае, если пользователь вошел в систему уже B работает сейчас.

B начинает звонить C. C startServiceдля IntentServiceD. Это результаты в этом стеке:

(A)> B> C> D

Из метода onHandleIntent в D событие отправляется ResultReceiver R.

Теперь R обрабатывает это событие, предоставляя пользователю диалоговое окно, в котором он может выбрать заводскую настройку приложения (удалить базу данных, sharedPrefs и т. Д.).

После сброса к заводским настройкам я хочу перезапустить приложение (чтобы закрыть все действия) и только снова запустить A, который затем запускает логин ActivityL и завершает себя:

(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, потому что ServiceIntentD также может вызываться из фоновой задачи, которая запускается AlarmManager.

Так, как я мог решить это, чтобы стек активности стал (A)> L?

Прикрепленный
источник

Ответы:

284

Вы можете использовать его PendingIntentдля запуска запуска в будущем, а затем для закрытия приложения.

Intent mStartActivity = new Intent(context, StartActivity.class);
int mPendingIntentId = 123456;
PendingIntent mPendingIntent = PendingIntent.getActivity(context, mPendingIntentId,    mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager mgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
System.exit(0);
Олег Кошкин
источник
5
Это отлично сработало для меня! Я просто использовал android.os.Process.killProcess (android.os.Process.myPid ()); через System.exit ();
FDIM
29
На устройствах 4.3 и 4.4 (все, что я тестировал) это, похоже, убивает текущую активность, а затем запускает новое поверх старого. Я 2 актива глубоко (основной -> префы). Нажатие на кнопку возвращает меня к старому приложению, один экран назад.
Mgamerz
5
В моем случае System.exit (0) не работал, так как транзакция откатывалась. Вместо этого я использовал activity.finish (); и это работает просто отлично.
объединение
6
@Qulin, ребята! Ты не можешь быть серьезным! Этот пример больше похож на направление, чем на реальный пример. Вы должны изменить этот фрагмент, указав имя начальной деятельности, идентификатор намерения и механику выхода, что бы вы ни использовали. Не копируйте слепо, вставьте его.
Олег Кошкин
19
Это больше не работает с Android Q из-за новых ограничений на фоновую активность developer.android.com/preview/privacy/…
Марко Ригини
103

Вы можете просто позвонить:

public static void triggerRebirth(Context context, Intent nextIntent) {
    Intent intent = new Intent(context, YourClass.class);
    intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
    intent.putExtra(KEY_RESTART_INTENT, nextIntent);
    context.startActivity(intent);
    if (context instanceof Activity) {
      ((Activity) context).finish();
    }

    Runtime.getRuntime().exit(0);
}

Который используется в библиотеке ProcessPhoenix


Как альтернатива:

Вот немного улучшенная версия ответа @Oleg Koshkin.

Если вы действительно хотите возобновить свою деятельность, включая уничтожение текущего процесса, попробуйте следующий код. Поместите его в HelperClass или там, где вам это нужно.

public static void doRestart(Context c) {
        try {
            //check if the context is given
            if (c != null) {
                //fetch the packagemanager 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);
                        //create a pending intent so the application is restarted after System.exit(0) was called. 
                        // We use an AlarmManager to call this intent in 100ms
                        int mPendingIntentId = 223344;
                        PendingIntent mPendingIntent = PendingIntent
                                .getActivity(c, mPendingIntentId, mStartActivity,
                                        PendingIntent.FLAG_CANCEL_CURRENT);
                        AlarmManager mgr = (AlarmManager) c.getSystemService(Context.ALARM_SERVICE);
                        mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
                        //kill the application
                        System.exit(0);
                    } else {
                        Log.e(TAG, "Was not able to restart application, mStartActivity null");
                    }
                } else {
                    Log.e(TAG, "Was not able to restart application, PM null");
                }
            } else {
                Log.e(TAG, "Was not able to restart application, Context null");
            }
        } catch (Exception ex) {
            Log.e(TAG, "Was not able to restart application");
        }
    }

Это также повторно инициализирует классы jni и все статические экземпляры.

mikepenz
источник
1
Это хорошее решение, но оно задержит на несколько секунд, пока не перезапустит ваше приложение, даже если вы уменьшили 100 миллисекунд. Тем не менее, эта библиотека ProcessPhoenix от Jack Wharton делает это лучше и быстрее, но не стоит добавлять библиотеку только для этой функции внутри приложения.
blueware
@blueware Я обновил свой ответ и добавил код, который используется внутри ProcessPhonix
mikepenz
@mikepenz, этот парень "Ilya_Gazman" сделал намного лучше и без использования такой библиотеки.
blueware
3
@blueware - за исключением того, что решение Ильи не перезапустит процесс, поэтому статические данные или загруженные библиотеки NDK не будут правильно переинициализированы.
Тед Хопп,
Некоторые устройства Huawei и Samsung имеют ограничения AlarmManagerи неправильное поведение при использовании этого решения. Есть ли лучший подход?
BlueWare
69

Джейк Уортон недавно опубликовал свою библиотеку ProcessPhoenix , которая делает это надежным способом. Вам в основном нужно только позвонить:

ProcessPhoenix.triggerRebirth(context);

Библиотека автоматически завершит вызывающее действие, завершит процесс приложения и впоследствии перезапустит действие приложения по умолчанию.

TBieniek
источник
Кажется, это работает, но я получаю сбой (о котором сообщается). Не уверен, что это идеально.
BK-
1
У меня никогда не было проблем с библиотекой, но вы можете сообщить об ошибке на github.com/JakeWharton/ProcessPhoenix/issues
TBieniek
Ага, я отозвал свой комментарий, потому что я не посмотрел на сообщение достаточно близко. Я пропустил фильтр намерений при запуске по умолчанию. Возможно, стоит отметить точные намеренные фильтры.
BK-
1
Это пока лучшее решение.
yongsunCN
1
@Shambhu, вы должны добавить тег <category android:name="android.intent.category.DEFAULT" />к вашей активности по умолчанию <intent-filter> в манифесте приложения.
Мухаммед Рефаат
57

Я немного изменил ответ Ilya_Gazman для использования новых API (IntentCompat устарел, начиная с API 26). Runtime.getRuntime (). Exit (0) кажется лучше, чем System.exit (0).

 public static void triggerRebirth(Context context) {
    PackageManager packageManager = context.getPackageManager();
    Intent intent = packageManager.getLaunchIntentForPackage(context.getPackageName());
    ComponentName componentName = intent.getComponent();
    Intent mainIntent = Intent.makeRestartActivityTask(componentName);
    context.startActivity(mainIntent);
    Runtime.getRuntime().exit(0);
}
android_dev
источник
8
Непосредственно из документов : « Звонок System.exit(n) фактически эквивалентен звонку: Runtime.getRuntime().exit(n) ». Внутренне System.exit()просто оборачивается и звонит Runtime.getRuntime().exit(). Нет ничего «лучшего» ни в одном, ни в другом (если не беспокоиться о том, сколько набирает текст или об одном дополнительном слое вызовов методов).
Тед Хопп,
где и когда вызывать вышеуказанный метод?
Маквин
1
@ Маквин, ты сам решаешь, где это назвать. Мой случай был перезапустить приложение после смены языка.
android_dev
@TedHopp комментирует каждый ответ как "не очень хороший", у вас есть какое-нибудь реальное решение? Не будучи саркастичным, действительно нужно воссоздать приложение без какого-либо следа; от статических переменных до экземпляров классов.
Фарид
1
@FARID - Любое из решений, которое включает вызов Runtime.getRuntime().exit(0)(или System.exit(0)), вероятно, будет работать. Некоторые из моих «не очень хороших» комментариев относятся к ответам (например, к письму Ильи Газмана, который с тех пор был отредактирован для включения такого вызова.
Тед Хопп
37

IntentCompat.makeRestartActivityTask

Новый способ сделать это, используя IntentCompat.makeRestartActivityTask

Создайте намерение, которое можно использовать для повторного запуска задачи приложения в ее базовом состоянии. Это похоже на makeMainActivity (ComponentName), но также устанавливает флаги Intent.FLAG_ACTIVITY_NEW_TASK и FLAG_ACTIVITY_CLEAR_TASK.

PackageManager packageManager = context.getPackageManager();
Intent intent = packageManager.getLaunchIntentForPackage(context.getPackageName());
ComponentName componentName = intent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(componentName);
context.startActivity(mainIntent);
System.exit(0);
Илья Газман
источник
6
Это перезапускает задачу, но не перезапускает процесс или даже Applicationобъект. Поэтому любые staticданные, данные, инициализированные при создании Applicationклассов, или jni, остаются в их текущем состоянии и не инициализируются повторно.
Тед Хопп
2
@TedHopp О, я пропустил эту часть. Я добавил System.exit (0); Но я не уверен на 100%, что это сработает. Я
проверю это позже
1
Лучшее решение без использования библиотеки с открытым исходным кодом, чтобы сделать это. Руки вверх и спасибо за этот ответ, +1
голубая
4
К сожалению, IntentCompat.makeRestartActivityTaskсейчас устарела . Если вы проверяете исходный код , это так же просто, как просто добавить флаги Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK.
Пол Ламмерцма
IntentCompat.makeRestartActivityTask удалено
luckyhandler
28

Есть действительно хороший трюк. Моя проблема заключалась в том, что в какой-то действительно старой C ++ jni библиотеке произошла утечка ресурсов. В какой-то момент он перестал функционировать. Пользователь попытался выйти из приложения и запустить его снова - безрезультатно, потому что завершение действия - это не то же самое, что завершение (или уничтожение) процесса. (Кстати, пользователь может перейти к списку запущенных приложений и остановить его оттуда - это будет работать, но пользователи просто не знают, как завершать приложения.)

Если вы хотите наблюдать за эффектом этой функции, добавьте staticпеременную к своей деятельности и увеличивайте ее, скажем, нажатием кнопки. Если вы выйдете из активности приложения, а затем снова вызовете приложение, эта статическая переменная сохранит свое значение. (Если приложение действительно было закрыто, переменной будет присвоено начальное значение.)

(И я должен прокомментировать, почему я не хотел вместо этого исправлять ошибку. Библиотека была написана десятилетия назад и с тех пор утечка ресурсов. Руководство считает, что это всегда работало . Стоимость предоставления исправления вместо обходного пути ... Я думаю, вы поняли.)

Теперь, как я могу сбросить разделяемую библиотеку jni (она же динамическая, .so) в исходное состояние? Я решил перезапустить приложение как новый процесс.

Хитрость в том, что System.exit () закрывает текущее действие, а Android заново создает приложение с одним действием меньше.

Итак, код:

/** This activity shows nothing; instead, it restarts the android process */
public class MagicAppRestart extends Activity {
    // Do not forget to add it to AndroidManifest.xml
    // <activity android:name="your.package.name.MagicAppRestart"/>
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        System.exit(0);
    }
    public static void doRestart(Activity anyActivity) {
        anyActivity.startActivity(new Intent(anyActivity.getApplicationContext(), MagicAppRestart.class));
    }
}

Вызывающее действие просто выполняет код MagicAppRestart.doRestart(this);, вызывающее действие onPause()выполняется, а затем процесс создается заново. И не забудьте упомянуть об этой активности в AndroidManifest.xml

Преимущество этого метода в том, что нет задержек.

UPD: в Android 2.x он работал, но в Android 4 что-то изменилось.

18446744073709551615
источник
3
я использовал activity.startActivity (i); System.exit (0); гениальное решение
max4ever
5
Это решение закрывает приложение для меня, но оно не перезапускается. По крайней мере, на Android 4.3.
Кирилл Рахман
1
На самсунге галактика мега андроид 4.2.2 вызывает бесконечный цикл перезапуска. Так что приложение не запустится снова.
Ганхан
@ Gunhan 1) что произойдет, если вы замените System.exit(0)на android.os.Process.killProcess(android.os.Process.myPid());? 2) бесконечный цикл, скорее всего, означает, что они не удаляют верхнюю активность при перезапуске приложения. В принципе, вы можете добавить статическую логическую переменную, установить ее в значение true, прежде чем вызывать операцию перезапуска, и после перезапуска она будет иметь значение false. Таким образом, действие может выяснить, произошел ли перезапуск или нет (и если это произошло, просто завершите () ). OTOH, ваш отчет означает, что фокус не работает одинаково на всех устройствах.
18446744073709551615
@Gunham Если вы запускаете ту же активность, которая вызывает перезапуск, то это будет бесконечный цикл на любом устройстве.
Лукас Ханачек
23

Мое решение не перезапускает процесс / приложение. Это только позволяет приложению «перезапустить» домашнюю активность (и отклонить все остальные действия). Это выглядит как перезагрузка для пользователей, но процесс такой же. Я думаю, что в некоторых случаях люди хотят достичь этого эффекта, поэтому я просто оставляю это здесь, к вашему сведению.

public void restart(){
    Intent intent = new Intent(this, YourHomeActivity.class);
    this.startActivity(intent);
    this.finishAffinity();
}
yongsunCN
источник
15

Хорошо, я провела рефакторинг своего приложения, и я не закончу A автоматически. Я позволю этому бежать всегда и заканчиваю это через onActivityResultсобытие. Таким образом, я могу использовать FLAG_ACTIVITY_CLEAR_TOP+ FLAG_ACTIVITY_NEW_TASKфлаги, чтобы получить то, что я хочу:

public class A extends Activity {

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        finish();
    }

    protected void onResume() {
        super.onResume();
        // ...
        if (loggedIn) {
            startActivityForResult(new Intent(this, MainActivity.class), 0);
        } else {
            startActivityForResult(new Intent(this, LoginActivity.class), 0);
        }
    }
}

и в ResultReceiver

@Override
public void onClick(DialogInterface dialog, int which) {
    MyApp.factoryReset();
    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);
}

Спасибо, в любом случае!

Прикрепленный
источник
23
Это не перезапустит приложение, а только заново создаст классы. Таким образом, любые статические переменные внутри классов будут сохранять значения из предыдущих прогонов.
Брайан Уайт
14
Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage( getBaseContext().getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
Нирав Ранпара
источник
24
Это не перезапустит приложение, а только заново создаст классы. Таким образом, любые статические переменные внутри классов будут сохранять значения из предыдущих прогонов.
Брайан Уайт
14

Единственный код, который не вызвал «Ваше приложение неожиданно закрылось», выглядит следующим образом. Это также не устаревший код, который не требует внешней библиотеки. Это также не требует таймера.

public static void triggerRebirth(Context context, Class myClass) {
    Intent intent = new Intent(context, myClass);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    context.startActivity(intent);
    Runtime.getRuntime().exit(0);
}
Haskell McRavin
источник
8

Я обнаружил, что это работает в API 29 и более поздних версиях - с целью уничтожения и перезапуска приложения, как если бы пользователь запустил его, когда оно не работало.

public void restartApplication(final @NonNull Activity activity) {
   // Systems at 29/Q and later don't allow relaunch, but System.exit(0) on
   // all supported systems will relaunch ... but by killing the process, then
   // restarting the process with the back stack intact. We must make sure that
   // the launch activity is the only thing in the back stack before exiting.
   final PackageManager pm = activity.getPackageManager();
   final Intent intent = pm.getLaunchIntentForPackage(activity.getPackageName());
   activity.finishAffinity(); // Finishes all activities.
   activity.startActivity(intent);    // Start the launch activity
   System.exit(0);    // System finishes and automatically relaunches us.
}

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

<intent-filter>
    <action android:name="android.intent.action.VIEW"/>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

Я видел комментарии, утверждающие, что категория DEFAULT необходима, но я не нашел, чтобы это имело место. Я подтвердил, что объект Application в моем приложении воссоздан, поэтому я считаю, что процесс действительно был убит и перезапущен.

Единственная цель, для которой я использую это, - перезапустить приложение после того, как пользователь включил или отключил отчеты о сбоях для Firebase Crashlytics. Согласно их документам, приложение должно быть перезапущено (процесс убит и заново создан), чтобы это изменение вступило в силу.

Марк Питерс
источник
7

Лучший способ полностью перезапустить приложение - это перезапустить его, а не просто перейти к операции с FLAG_ACTIVITY_CLEAR_TOPи FLAG_ACTIVITY_NEW_TASK. Поэтому мое решение состоит в том, чтобы сделать это из вашего приложения или даже из другого приложения, единственное условие - знать имя пакета приложения (пример: ' com.example.myProject ')

 public static void forceRunApp(Context context, String packageApp){
    Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(packageApp);
    launchIntent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(launchIntent);
}

Пример использования перезапуска или запуска appA из appB :

forceRunApp(mContext, "com.example.myProject.appA");

Вы можете проверить, работает ли приложение:

 public static boolean isAppRunning(Context context, String packageApp){
    ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    List<ActivityManager.RunningAppProcessInfo> procInfos = activityManager.getRunningAppProcesses();
    for (int i = 0; i < procInfos.size(); i++) {
        if (procInfos.get(i).processName.equals(packageApp)) {
           return true;
        }
    }
    return false;
}

Примечание : я знаю, что этот ответ немного не в тему, но он может быть действительно полезным для кого-то.

Choletski
источник
5

Мой лучший способ перезапустить приложение - использовать finishAffinity();
С, finishAffinity();может использоваться только на версиях JELLY BEAN, поэтому мы можем использовать его ActivityCompat.finishAffinity(YourCurrentActivity.this);для более низких версий.

Затем используйте Intentдля запуска первое действие, поэтому код будет выглядеть так:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
    finishAffinity();
    Intent intent = new Intent(getApplicationContext(), YourFirstActivity.class);
    startActivity(intent);
} else {
    ActivityCompat.finishAffinity(YourCurrentActivity.this);
    Intent intent = new Intent(getApplicationContext(), YourFirstActivity.class);
    startActivity(intent);
}

Надеюсь, поможет.

Хуссейн Н.Д.
источник
1
Это завершает все действия в текущей задаче, но не перезапускает процесс и даже не создает заново объект Application. Поэтому любые статические данные, данные, инициализированные при создании Приложения, или классами jni, остаются в их текущем состоянии и не инициализируются повторно.
Тед Хопп
3

Попробуйте использовать FLAG_ACTIVITY_CLEAR_TASK

Педро Лоурейро
источник
HM разрабатывается для 2.1: Intent.FLAG_ACTIVITY_CLEAR_TASK не может быть решена
Застрял
Извините - С тех пор: API Level 11 developer.android.com/reference/android/content/…
Педро Лоурейро
3

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

Intent i = getBaseContext().getPackageManager()
             .getLaunchIntentForPackage( getBaseContext().getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
Алиреза Ганбариния
источник
Это перезапускает задачу, но не перезапускает процесс или даже Applicationобъект. Поэтому любые статические данные, данные, инициализированные при создании Applicationклассов, или jni, остаются в их текущем состоянии и не инициализируются повторно.
Тед Хопп
3

попробуй это:

Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName());
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
veeson
источник
1
Как и в случае с любым другим ответом, уже предлагающим то же самое, это не перезапустит приложение, а только заново создаст классы. Таким образом, любые статические данные в процессе не будут сброшены.
Тед Хопп,
2

Прямой запуск начального экрана с помощью FLAG_ACTIVITY_CLEAR_TASKи FLAG_ACTIVITY_NEW_TASK.

Ицзюнь Ли
источник
2

Мне пришлось добавить обработчик, чтобы задержать выход:

 mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 200, mPendingIntent);
        final Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                Runtime.getRuntime().exit(0);
            }
        }, 100);
Andy7229082
источник
2

Использование:

navigateUpTo(new Intent(this, MainActivity.class));

Это работает, начиная с уровня API 16 (4.1), я считаю.

Питер Мортенсен
источник
1

Вы можете использовать startInstrumentationметод Activity. Вам нужно реализовать пустой Instrumentationи указанный в манифесте. После этого вы можете вызвать этот метод для перезапуска вашего приложения. Как это:

try {           
    InstrumentationInfo info = getPackageManager().queryInstrumentation(getPackageName(), 0).get(0);
    ComponentName component = new ComponentName(this, Class.forName(info.name));
    startInstrumentation(component, null, null);
} catch (Throwable e) {             
    new RuntimeException("Failed restart with Instrumentation", e);
}

Я получаю имя класса Instrumentation динамически, но вы можете жестко его кодировать. Некоторым нравится это:

try {           
    startInstrumentation(new ComponentName(this, RebootInstrumentation.class), null, null); 
} catch (Throwable e) {             
    new RuntimeException("Failed restart with Instrumentation", e);
}

Звоните, startInstrumentationсделайте перезагрузку вашего приложения. Прочитайте описание этого метода. Но это может быть небезопасно, если вы ведете себя как приложение для уничтожения

Enyby
источник
1

Приложение, над которым я работаю, должно дать пользователю возможность выбирать, какие фрагменты отображать (фрагменты динамически изменяются во время выполнения). Лучшим решением для меня было полностью перезапустить приложение.

Поэтому я перепробовал множество решений, и ни одно из них мне не помогло, но вот:

final Intent mStartActivity = new Intent(SettingsActivity.this, Splash.class);
final int mPendingIntentId = 123456;
final PendingIntent mPendingIntent = PendingIntent.getActivity(SettingsActivity.this, mPendingIntentId, mStartActivity,
                    PendingIntent.FLAG_CANCEL_CURRENT);
final AlarmManager mgr = (AlarmManager) SettingsActivity.this.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
this.finishAffinity(); //notice here
Runtime.getRuntime().exit(0); //notice here

Надеюсь, что это поможет кому-то еще!

hzitoun
источник
0

попробуй это:

private void restartApp() {
    Intent intent = new Intent(getApplicationContext(), YourStarterActivity.class);
    int mPendingIntentId = MAGICAL_NUMBER;
    PendingIntent mPendingIntent = PendingIntent.getActivity(getApplicationContext(), mPendingIntentId, intent, PendingIntent.FLAG_CANCEL_CURRENT);
    AlarmManager mgr = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
    mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
    System.exit(0);
}
Мухаммед Мубин
источник
-1

С библиотекой процесса Феникс . Активность, которую вы хотите перезапустить, называется «A».

Java вкус

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

Kotlin аромат

// kotlin
fun restart() {
    ProcessPhoenix.triggerRebirth(context)
}
Рэймонд Шенон
источник
Это приводит к неудачному отключению отладчика.
DrSatan1
-3

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

Фрагмент:

activity?.recreate()

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

recreate()

источник
3
Это совсем не то, что ОП хочет сделать.
Тед Хопп,