Jak zrestartować Aktywność w Androidzie


381

Jak zrestartować system Android Activity? Próbowałem następujące, ale po Activityprostu rezygnuje.

public static void restartActivity(Activity act){

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

}

9
aktywność kończy się, ponieważ nazwano „act.finish ();” natychmiast po utworzeniu działania ...
Nikhil Dinesh

1
nieaktualna metoda
pedjjj

Odpowiedzi:


623

Tak zmieniłem motyw:

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

Zasadniczo dzwonię finish()pierwszy i używam dokładnie tego samego celu, od którego zaczęło się to działanie. To wydaje się załatwić sprawę?

AKTUALIZACJA: Jak wskazał Ralf poniżej, Activity.recreate()jest to droga do wyjścia w API 11 i późniejszych wersjach. Jest to preferowane, jeśli jesteś w środowisku API11 +. Nadal możesz sprawdzić bieżącą wersję i wywołać powyższy fragment kodu, jeśli korzystasz z API 10 lub niższego. (Proszę nie zapomnieć o głosowaniu na odpowiedź Ralfa!)


36
A to jest warte oddania głosu? Nie był to wymóg wspomniany przez PO. W rzeczywistości może być pożądane.
EboMike,

9
Cóż, jeśli nie podoba ci się animacja, możesz ją wyłączyć (jak pokazano w odpowiedzi). To nie sprawia, że ​​moja odpowiedź jest błędna per se, po prostu nie pokazuje dodatkowych opcji, które możesz swobodnie dodać (i o które nie pytano w pytaniu).
EboMike,

28
Myślę, że pomyliłeś się. Opinia negatywna oznacza złą / złą odpowiedź, a opinia pozytywna oznacza, że ​​odpowiedź jest świetna. O tym, jak wspaniała jest odpowiedź w porównaniu z innymi, świadczy liczba pozytywnych opinii. Widzę, że próbujesz promować swoją odpowiedź, ale niewłaściwie używasz systemu do tego celu.
EboMike,

8
+1 - działało to dla mnie świetnie, a jak mówisz, animacja była czymś, czego chciałem, więc użytkownik wie, że się restartuje. FWIW, ustanawiam zasadę, aby nigdy nie głosować w dół na odpowiedzi innych użytkowników, gdy udzielam alternatywnej odpowiedzi na pytanie, chociaż czasami głosuję w górę, gdy moja odpowiedź jest zdeklasowana (nie mówiąc, że to się tutaj stało, tylko to, że to robię) .
Michael Bray,

4
EboMike i Ben: Oba rozwiązania odpowiedziały na pytanie PO. Głosowanie w dół na czyjąś odpowiedź wyłącznie z powodu „estetycznego” nie jest, cóż, świetne. Zniechęciłbym każdego, by robił to tutaj w
Stackoverflow

368

Od poziomu API 11 (Honeycomb), możesz wywołać metodę createate () działania (dzięki tej odpowiedzi).

Metoda restore () działa jak zmiana konfiguracji, dlatego też metody onSaveInstanceState () i onRestoreInstanceState () są również wywoływane, jeśli ma to zastosowanie.


3
co jeśli poprzednie działanie nazywało to za pomocą startActivityForResult?
deweloper Androida

1
Cóż, to poprawna odpowiedź, jeśli nie musisz obsługiwać niczego niższego niż API 11.
Edward Falk

@EdwardFalk jest jakaś funkcja, która robi to w bibliotece wsparcia?
programista Androida

2
To nie działa we wszystkich przypadkach. Jeśli masz otwartą szufladę nawigacji podczas wywoływania funkcji odtwarzania (), pozostanie otwarta podczas odtwarzania, co oznacza, że ​​zapisuje stan, co może być niepożądane.
Chapz,

To ja nie chcę, żeby państwo zostało uratowane. Czasami ludzie chcą po prostu czystego restartu, wtedy powinni skorzystać z odpowiedzi EboMike.
Kimi Chiu

132

Przed pakietem SDK 11 można to zrobić w następujący sposób:

public void reload() {
    Intent intent = getIntent();
    overridePendingTransition(0, 0);
    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
    finish();
    overridePendingTransition(0, 0);
    startActivity(intent);
}

W telefonie HTC Desire nadal pozostają animacje (przynajmniej jeśli są używane w metodzie onConfigurationChanged). Nie zawsze występują, ale przy użyciu kodu EboMike nie zawsze występują.
Juozas Kontvainis

8
Nie działa to w przypadku głównej aktywności rozpoczętej przez program uruchamiający. Twoja aktywność zostanie ukryta z powodu niektórych flag ustawionych w tym celu. W przeciwnym razie działa ładnie.
Thomas Ahle,

Słuszna uwaga. ma sens, ponieważ wywołuje metodę finish () z działania podstawowego na stosie.
Ben

Wywołanie tego, gdy zmieniamy motyw działania, wydaje się wydobywać prędkość (bez animacji)
Ashok Goli,

3
+1 działa dobrze, nawet dla mnie z główną aktywnością. Powinieneś jednak zadzwonić odpowiednio overridePendingTransition(0, 0);po, finish()a startActivity()nie tam, gdzie to
nazwałeś

115

Wystarczy połączyć odpowiedzi Ralfa i Bena (w tym zmiany wprowadzone w komentarzach):

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);
}

8
Najlepsza odpowiedź ze wszystkich. Wierzcie lub nie, ale nadal obsługuję urządzenia API 3, a wartość VERSION.SDK_INT wymaga API 4. :)
Edward Falk

31

Użyłem tego kodu, więc nadal mogłem obsługiwać starsze wersje Androida i używać go recreate()w nowszych wersjach Androida.

Kod:

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

Próba:

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());
        }
    }
}

to dla mnie świetna robota !!
papo

22

To rozwiązanie działało dla mnie.

Najpierw zakończ działanie, a następnie uruchom je ponownie.

Przykładowy kod:

public void restartActivity(){
    Intent mIntent = getIntent();
    finish();
    startActivity(mIntent);
}

20

Jest to zdecydowanie najprostszy sposób na wznowienie bieżącej aktywności:

finish();
startActivity(getIntent());

19

Nazwij tę metodę

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

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

Dzięki,


1
Myślę, że OP chce wznowić każdą aktywność, nie tylko pierwszą, ale było to dla mnie pomocne.
Kristopher Johnson

1
Dwie flagi dobrze wiedzieć, moja sprawa zdawała się bez nich nic nie robić.
Owen B

1
działało dzięki tobie! niech cię Bóg błogosławi.
Vivek

16

Mimo że udzielono na nie wielu odpowiedzi.

Jeśli zrestartujesz aktywność z fragmentu, zrobiłbym to tak:

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);
        }
    });

Więc możesz myśleć, że to trochę przesada? Ale Handlerpublikowanie pozwala wywołać to w metodzie cyklu życia. Użyłem tej metody w onRestart/ onResumepodczas sprawdzania, czy stan zmienił się między powrotem użytkownika do aplikacji. (zainstalowałem coś).

Bez Handlerwywołania w dziwnym miejscu po prostu zabije to działanie i nie uruchomi go ponownie.

Możesz zadawać pytania.

Na zdrowie Chris


2
Świetne rozwiązanie i bardzo dobre uzasadnienie / wyjaśnienie dla programu obsługi.
JRomero,

1
Dlaczego dzwonisz dwukrotnie, by „przesłonićPendingTransition”?
programista Androida

1
@androiddeveloper Nie pamiętam, myślę, że to było obejście błędu. Możesz wywołać go raz przed startActivity () i zrobi to, co powiedziano.
Chris.Jenkins

Po zaimplementowaniu tego w mojej funkcji onResume gra zatrzymuje się na mojej metodzie onStop i ma czarny ekran ... nie jestem pewien, dlaczego
Scumble373

1
Cześć Chris, możesz wyjaśnić to nieco dalej „Bez Handlera, jeśli nazwiesz go w dziwnym miejscu, po prostu zabije to działanie i nie uruchomi go ponownie”. ?
parvez rafi

15

Cóż, nie ma go na liście, ale zestawienie niektórych, które jest już opublikowane:

if (Build.VERSION.SDK_INT >= 11) {
    recreate();   
} else {
    Intent intent = getIntent();
    finish();
    startActivity(intent);
}

Działa dla mnie .. dzięki .. ale chcę cię zapytać: dlaczego po usunięciu pierwszej części kodu (tej, która sprawdza SDK_INT) moja aplikacja działa stosunkowo wolno? !! .. kiedy ponownie dołączam kod, działa on relatywnie i oczywiście znacznie szybciej !!!
McLan,

2
Nie jestem tego pewien. Cóż, jeśli używasz zestawu SDK, który ma wartość> = 11, następnie createate () powinno być szybsze niż uzyskanie zamiaru, zakończenie, a następnie ponowne uruchomienie. Zakończ wywołuje kod uruchamiający się w trybie OnStop i ponownie tworzy kod działający, taki jak zmiana orientacji ... więc nie jest tak wiele do zrobienia.
Codeversed

4

W połączeniu z dziwnym zachowaniem cyklu życia SurfaceView z kamerą . Przekonałem się, że metoda replace () nie zachowuje się dobrze w cyklu życia SurfaceViews. SurfaceDestroyed nigdy nie jest wywoływany podczas cyklu rekreacyjnego. Jest wywoływany po onResume (dziwne), w którym to momencie mój SurfaceView zostaje zniszczony.

Oryginalny sposób odtworzenia działania działa dobrze.

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

Nie mogę dokładnie zrozumieć, dlaczego tak jest, ale jest to tylko obserwacja, która, mam nadzieję, może poprowadzić innych w przyszłości, ponieważ naprawiła moje problemy, które miałem z SurfaceViews


4

Zastanawiam się, dlaczego nikt nie wspomniał o tym, Intent.makeRestartActivityTask()co dokładnie czyni ten cel.

Wykonaj zamiar, którego można użyć do ponownego uruchomienia zadania aplikacji * w stanie podstawowym.

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

Ta metoda ustawia Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASKjako domyślne flagi.


3

W rzeczywistości poniższy kod jest prawidłowy dla poziomów API 5 i wyższych, więc jeśli docelowy interfejs API jest niższy niż ten, otrzymasz coś bardzo podobnego do kodu EboMike.

intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
overridePendingTransition(0, 0);

3

Jest jeden zhackowany sposób, który powinien działać przy każdej aktywności, w tym głównej.

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

Kiedy orientacja się zmienia, Android zazwyczaj odtworzy Twoją aktywność (chyba że ją zastąpisz). Ta metoda jest przydatna w przypadku obrotu o 180 stopni, gdy Android nie odtworzy Twojej aktywności.


3
public void onRestart() {
    super.onRestart();
    Intent intent=new Intent();
    intent.setClass(act, act.getClass());
    finish();
    act.startActivity(intent);
}

spróbuj użyć tego ..


3

Rozwiązaniem twojego pytania jest:

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

Musisz przerzucić do kontekstu działania, aby rozpocząć nowe działanie, a także zakończyć bieżące działanie.

Mam nadzieję, że to pomocne .. i działa dla mnie.


1

Jeśli usuniesz ostatni wiersz, utworzysz nowe actdziałanie, ale Twoja stara instancja będzie nadal żywa.

Czy musisz zrestartować działanie tak, jak przy zmianie orientacji (tzn. Twój stan jest zapisany i przekazany onCreate(Bundle))?

Jeśli tego nie zrobisz, jednym z możliwych obejść byłoby użycie jednego dodatkowego, pozorowanego działania, które byłoby uruchamiane od pierwszego działania, i którego zadaniem jest rozpoczęcie nowej instancji. Lub po prostu opóźnij połączenie zact.finish() , po uruchomieniu nowego.

Jeśli chcesz uratować większość stanu, wchodzisz na dość głębokie wody, ponieważ przekazanie wszystkich właściwości swojego stanu, szczególnie bez wycieku starego kontekstu / działania, nie jest trywialne, poprzez przekazanie go do nowej instancji.

Proszę określić, co próbujesz zrobić.


1
Mam przycisk, który stosuje różne motywy do aplikacji, po zastosowaniu motywu jest zapisywany w preferencjach, aktywność root uruchamia się ponownie, odczytuje motyw z preferencji, stosuje motyw w onCreate (). Okazuje się, że powyższy kod działa dobrze, jeśli aktywność nie jest instancją typu single_instance. Nie jestem pewien, czy to najlepsza praktyka.

Obecnie nie ma czystego, wybrukowanego SDK sposobu na wznowienie aktywności, AFAIK - jeśli niczego nie wyciekniesz, być może warto iść :)
Dimitar Dimitrov

0

Tak to robię.

        val i = Intent(context!!, MainActivity::class.java)
        i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
        startActivity(i)

-1

Jeśli dzwonisz z jakiegoś fragmentu, zrób to poniżej kodu.

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

-4

możesz po prostu użyć

onRestart ()

metoda w następujący sposób

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

i wywołaj onRestart (), gdzie chcesz zrestartować bieżącą aktywność


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.