Как перезапустить активность в Android

382

Как перезапустить Android Activity? Я попробовал следующее, но Activityпросто выходит.

public static void restartActivity(Activity act){

        Intent intent=new Intent();
        intent.setClass(act, act.getClass());
        act.startActivity(intent);
        act.finish();

}
Самет ОЗТОПРАК
источник
9
действие прекращается, потому что вы вызвали "act.finish ();" сразу после создания активности ...
Нихил Динеш
1
устаревший метод
pedjjj

Ответы:

623

Я сделал мой переключатель темы следующим образом:

Intent intent = getIntent();
finish();
startActivity(intent);

По сути, я звоню finish()первым и использую то же самое намерение, с которого началась эта деятельность. Это, кажется, делает трюк?

ОБНОВЛЕНИЕ: Как отметил Ральф ниже, Activity.recreate()это путь в API 11 и выше. Это предпочтительно, если вы находитесь в среде API11 +. Вы все еще можете проверить текущую версию и вызвать фрагмент кода выше, если вы используете API 10 или ниже. (Пожалуйста, не забудьте подтвердить ответ Ральфа!)

EboMike
источник
36
И это стоит понизить? Это не было требованием, упомянутым ФП. На самом деле, это может быть желательным.
EboMike
9
Ну, если вам не нравится анимация, вы можете отключить ее (как вы продемонстрировали в своем ответе). Это само по себе не делает мой ответ неверным, просто он не показывает некоторые дополнительные опции, которые вы можете добавить (и которые не были заданы в вопросе).
EboMike
28
Я думаю, вы ошиблись. Понижение означает неправильный / плохой ответ, а отрицание означает хороший ответ. Насколько велик ответ по сравнению с другими, показывает количество голосов. Я вижу, что вы пытаетесь продвигать свой ответ, но вы неправильно используете систему для этой цели.
EboMike
8
+1 - это отлично сработало для меня, и, как вы говорите, анимация - это то, чего я действительно хотел, так что пользователь знает, что она перезапускается. FWIW, я делаю правило никогда не переоценивать ответы других пользователей, когда я даю альтернативный ответ на вопрос, хотя иногда я делаю перевес, когда мой ответ отстает (не говоря о том, что здесь произошло, просто я это делаю) ,
Майкл Брей
4
EboMike и Ben: Оба ваших решения ответили на вопрос ОП. Голосовать за чей-то ответ исключительно из-за «эстетической» причины - ну, не очень. Я бы никому не рекомендовал делать это здесь, в Stackoverflow ...
ChuongPham
368

Начиная с уровня API 11 (Honeycomb), вы можете вызывать метод воссоздания () действия (благодаря этому ответу).

Метод refreshate () действует так же, как изменение конфигурации, поэтому ваши методы onSaveInstanceState () и onRestoreInstanceState () также вызываются, если это применимо.

Ralf
источник
3
Что если предыдущая операция назвала эту с помощью startActivityForResult?
разработчик Android
1
Что ж, это правильный ответ, если вам не нужно поддерживать что-то ниже API 11.
Эдвард Фальк,
@EdwardFalk есть ли функция, которая делает это в библиотеке поддержки?
Android-разработчик
2
Это работает не во всех случаях. Если у вас открыт навигационный ящик во время вызова метода create (), он будет оставаться открытым после восстановления, что означает сохранение состояния, что может быть нежелательным.
Чапз
Я тот, кто не хочет, чтобы государство было спасено. Иногда люди просто хотят перезагрузить компьютер, тогда им следует использовать ответ EboMike.
Кими Чиу
132

До SDK 11 способ сделать это выглядит так:

public void reload() {
    Intent intent = getIntent();
    overridePendingTransition(0, 0);
    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
    finish();
    overridePendingTransition(0, 0);
    startActivity(intent);
}
Бен
источник
В HTC Desire анимация все еще сохраняется (по крайней мере, при использовании в методе onConfigurationChanged). Они встречаются не всегда, но, используя код EboMike, они также встречаются не всегда.
Юозас Контвайнис
8
Это не работает в основной деятельности, запущенной программой запуска. Ваша деятельность в конечном итоге будет скрыта из-за некоторых флагов, установленных в намерении. В противном случае это работает хорошо.
Томас Але
Хорошая точка зрения. имеет смысл, потому что он вызывает finish () из базовой активности в стеке.
Бен
Вызывая это, пока мы меняем тему, кажется, выявляет скорость (без анимации)
Ашок Голи
3
+1 Работает нормально, у меня даже с основной Активностью. Тем не менее, вы должны звонить overridePendingTransition(0, 0);после finish()и startActivity(), соответственно, а не там, где вы это называли ...
caw
115

Просто чтобы объединить ответы Ральфа и Бена (включая изменения, сделанные в комментариях):

if (Build.VERSION.SDK_INT >= 11) {
    recreate();
} else {
    Intent intent = getIntent();
    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
    finish();
    overridePendingTransition(0, 0);

    startActivity(intent);
    overridePendingTransition(0, 0);
}
JustinMorris
источник
8
Лучший ответ из всех. Хотите верьте, хотите нет, я все еще поддерживаю устройства API 3, а для значения VERSION.SDK_INT требуется API 4. :)
Эдвард Фальк,
32

Я использовал этот код, так что я все еще мог поддерживать более старые версии Android и использовать recreate()на более новых версиях Android.

Код:

public static void restartActivity(Activity activity){
    if (Build.VERSION.SDK_INT >= 11) {
        activity.recreate();
    } else {
        activity.finish();
        activity.startActivity(activity.getIntent());
    }
}

Образец:

import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {
    private Activity mActivity;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mActivity = MainActivity.this;

        Button button = (Button) findViewById(R.id.restart_button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                restartActivity(mActivity);
            }
        });
    }

    public static void restartActivity(Activity activity) {
        if (Build.VERSION.SDK_INT >= 11) {
            activity.recreate();
        } else {
            activity.finish();
            activity.startActivity(activity.getIntent());
        }
    }
}
Томас Вос
источник
это отличная работа для меня!
Папо
22

Это решение сработало для меня.

Сначала завершите упражнение, а затем начните его снова.

Образец кода:

public void restartActivity(){
    Intent mIntent = getIntent();
    finish();
    startActivity(mIntent);
}
user3748515
источник
20

На сегодняшний день это самый простой способ перезапустить текущую активность:

finish();
startActivity(getIntent());
Абхишек Сони
источник
19

Вызовите этот метод

private void restartFirstActivity()
 {
 Intent i = getApplicationContext().getPackageManager()
 .getLaunchIntentForPackage(getApplicationContext().getPackageName() );

 i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK );
 startActivity(i);
 }

Спасибо,

Нихил Динеш
источник
1
Я думаю, что ОП хочет возобновить любую деятельность, не только первую, но это было полезно для меня.
Кристофер Джонсон
1
Два флага хорошо знать, мой случай, казалось, ничего не сделал без них.
Оуэн Б
1
это сработало благодаря вам! Будьте здоровы .
Вивек
16

Хотя на это уже отвечали несколько раз.

Если перезапустить активность из фрагмента, я бы сделал это так:

new Handler().post(new Runnable() {

         @Override
         public void run()
         {
            Intent intent = getActivity().getIntent();
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
            getActivity().overridePendingTransition(0, 0);
            getActivity().finish();

            getActivity().overridePendingTransition(0, 0);
            startActivity(intent);
        }
    });

Значит, вы думаете, это немного перебор? Но Handlerпубликация позволяет вызвать это в методе жизненного цикла. Я использовал это в onRestart/ onResumeметодов при проверке, изменилось ли состояние между пользователем, возвращающимся в приложение. (установлено что-то).

Без этого, Handlerесли вы вызовете его в нечетном месте, оно просто убьет действие и не перезапустит его.

Не стесняйтесь задавать любые вопросы.

Ура, Крис

Chris.Jenkins
источник
2
Отличное решение и очень хорошая аргументация / объяснение для хендлера.
JRomero
1
Почему вы дважды вызываете "overridePendingTransition"?
Android-разработчик
1
@androiddeveloper Не могу вспомнить, я думаю, что это было обходной ошибкой. Вы можете вызвать его один раз перед startActivity (), и он будет делать, как сказано.
Chris.Jenkins
После реализации этого в моей функции onResume игра останавливается на моем методе onStop и имеет черный экран ... не знаю почему
Scumble373
1
Привет Крис, можешь ли ты объяснить это немного дальше: «Без обработчика, если вы вызовете его в нечетном месте, он просто убьет действие и не перезапустит его». ?
Парвез Рафи
15

Ну, это не в списке, но комбо некоторых, которые уже размещены:

if (Build.VERSION.SDK_INT >= 11) {
    recreate();   
} else {
    Intent intent = getIntent();
    finish();
    startActivity(intent);
}
Codeversed
источник
Это работает для меня .. спасибо .. но я хочу спросить вас: почему, когда я удаляю первую часть кода (ту, которая проверяет SDK_INT), мое приложение работает, относительно, медленно? !! .. когда я снова присоединяю код, он запускается, относительно и, очевидно, намного быстрее !!!
Маклан
2
Не уверен в этом. Что ж, если вы используете SDK, который> = 11, то метод refresh () должен быть быстрее, чем получить намерение, завершить, а затем запустить его снова. Завершите вызов кода, который запускается в onStop, и воссоздайте код запуска, например, изменение ориентации ... так что это не так уж и много.
Codeversed
4

В сочетании со странным поведением SurfaceView в течение жизненного цикла с камерой . Я обнаружил, что метод create () плохо работает с жизненным циклом SurfaceView. SurfaceDestroyed никогда не вызывается во время цикла отдыха. Он вызывается после onResume (странно), после чего мой SurfaceView уничтожается.

Оригинальный способ воссоздания деятельности работает отлично.

Intent intent = getIntent();
finish();
startActivity(intent);

Я не могу точно понять, почему это так, но это всего лишь наблюдение, которое, мы надеемся, поможет другим в будущем, потому что оно устранило мои проблемы, которые у меня были с SurfaceViews.

The4thIceman
источник
4

Интересно, почему никто не упомянул, Intent.makeRestartActivityTask()что делает именно эту цель.

Создайте намерение, которое можно использовать для повторного запуска задачи приложения * в ее базовом состоянии.

startActivity(Intent.makeRestartActivityTask(getActivity().getIntent().getComponent()));

Этот метод устанавливает Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASKфлаги по умолчанию.

shkschneider
источник
3

На самом деле следующий код действителен для уровней API 5 и выше, поэтому, если ваш целевой API ниже, чем этот, вы получите нечто очень похожее на код EboMike.

intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
overridePendingTransition(0, 0);
Сэнди
источник
3

Есть один хакерский способ, который должен работать на любую деятельность, включая основную.

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);

Когда ориентация меняется, Android обычно воссоздает вашу активность (если вы не переопределите ее). Этот метод полезен для поворота на 180 градусов, когда Android не воссоздает вашу активность.

Ачал Дэйв
источник
3
public void onRestart() {
    super.onRestart();
    Intent intent=new Intent();
    intent.setClass(act, act.getClass());
    finish();
    act.startActivity(intent);
}

попробуйте использовать это ..

Amsheer
источник
3

Решение для вашего вопроса:

public static void restartActivity(Activity act){
    Intent intent=new Intent();
    intent.setClass(act, act.getClass());
    ((Activity)act).startActivity(intent);
    ((Activity)act).finish();
}

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

Надеюсь, что это полезно .. и работает для меня.

Раджеш Перам
источник
1

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

Вам нужно перезапустить действие, как при изменении ориентации (т.е. ваше состояние сохраняется и передается onCreate(Bundle))?

Если вы этого не сделаете, одним из возможных способов решения этой проблемы будет использование одного дополнительного фиктивного действия, которое будет запущено с первого действия, и заданием которого является запуск нового экземпляра. Или просто отложите звонок на act.finish(), после запуска нового.

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

Пожалуйста, укажите, что вы пытаетесь сделать.

Димитар Димитров
источник
1
У меня есть кнопка, которая применяет различные темы к приложению, после применения темы она сохраняется в предпочтении, корневая активность перезапускается, считывает тему из предпочтения, применяет тему в onCreate (). Оказывается, что приведенный выше код работает нормально, если активность не является single_instance. Не уверен, что это лучшая практика.
В настоящее время не существует чистого, проложенного с помощью SDK способа перезапуска вашей Активности, AFAIK - если вы ничего не пропускаете, возможно, вам стоит пойти :)
Димитар Димитров
0

Это способ, которым я делаю это.

        val i = Intent(context!!, MainActivity::class.java)
        i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
        startActivity(i)
MicroRJ
источник
-1

Если вы звоните из какого-то фрагмента, сделайте так, как показано ниже.

Intent intent = getActivity().getIntent();
getActivity().finish();
startActivity(intent);
Михир Триведи
источник
-4

Вы можете просто использовать

onRestart ()

метод следующим образом

 @Override
    protected void onRestart() {
        super.onRestart();
        setContentView(R.layout.add_entry);
    }

и вызовите onRestart (), где вы хотите перезапустить текущую активность

SuKu
источник
-5

Вызовите метод onCreate. НапримерonCreate(null);

kike0kike
источник