Jak zamknąć aktywność i wrócić do poprzedniej aktywności w Androidzie


144

Mam główne działanie, które po kliknięciu przycisku rozpoczyna nowe działanie, wykorzystałem do tego następujący kod:

Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);

Powyższy kod został uruchomiony z głównego działania.

Teraz w moim nowym działaniu, które jest wywoływane przez działanie główne, mam przycisk Wstecz. Kiedy kliknę ten przycisk Wstecz, chcę, aby moje nowe działanie zostało zamknięte i musi powrócić do pierwotnego głównego działania.

Próbowałem dzwonić super.finish()i po prostu finish() (z nowej aktywności), ale to zamyka całą moją aplikację (w tym moją główną aktywność).

Jak mogę po prostu zamknąć czynność, która jest aktualnie aktywna, a następnie powrócić do czynności głównej?

EDYTOWANE

Fakt, że przycisk Wstecz w telefonie zamyka również całą moją aplikację, prowadzi mnie do wniosku, że drugą czynność uruchomiłem nieprawidłowo?


OK, szukałem,

Utworzyłem działanie związane z ustawieniami, które używa tego samego kodu manifestu i tego samego kodu do uruchomienia działania.

W przypadku ustawień Aktywność, kiedy naciskam przycisk Wstecz, powraca do działania głównego.

Dzięki aktywności wspomnianej powyżej w głównym pytaniu po prostu zamyka całą moją aplikację.

Tak więc problem nie dotyczy kodu kończącego działanie, ale samego działania.


4
Nie potrzebujesz nawet przycisku Wstecz, po prostu pozwól użytkownikowi użyć klawisza Wstecz w telefonie i nie musisz nic robić.
Hoan Nguyen

Przycisk Wstecz w telefonie zamyka aplikację wejściową, a nie tylko moją dodatkową aktywność. Nie chcę zamykać głównej działalności.
Zapnologica

1
Przycisk „wstecz” nie powinien tego robić - czy możesz pokazać więcej swojego kodu?
peejaybee

W odpowiedzi na Twoją zmianę działanie drugorzędne wygląda dobrze na podstawie tego, co opublikowałeś. Myślę, że TGMCians prawdopodobnie ma właściwą odpowiedź i sprawdzasz swój manifest.
peejaybee

zobacz tę odpowiedź myślę, że to ci pomoże
Muhammad Helmi

Odpowiedzi:


201

Myślę, że wywołujesz finish()metodę MainActivityprzed rozpoczęciem SettingsActivity.

Scenariusz, który opisałeś, nastąpi na dwa sposoby:

ZARÓWNO

Ustawiono android:noHistory = "true"do MainActivitywewnątrz AndroidManifest.xml, co powoduje MainActivitysię finishautomatycznie po naciśnięciu przycisku Wstecz.

LUB

Przed przełączeniem się do „SettingsActivity” wywołałeś finish()swój MainActivity, co go zabija. Po naciśnięciu przycisku Wstecz, ponieważ żadna inna czynność nie jest ustawiona na stosie, wraca do ekranu głównego.


To by wyjaśniało, dlaczego przycisk „wstecz” w telefonie również odrzuca główną czynność.
peejaybee

Podczas debugowania zauważyłem, że wykonanie jest kontynuowane po zakończeniu (), więc zaleca się dodanie dodatkowo zwrotu.
do

Czy trzeci powód w tej odpowiedzi nie jest po prostu powtórzeniem pierwszego?
Pang

60

Możesz wrócić do poprzedniej czynności, wywołując po prostu finish () w bieżącej aktywności. Zwróć uwagę, że zostanie uruchomiony dowolny kod po wywołaniu finish () - możesz po prostu wykonać powrót po wywołaniu finish (), aby to naprawić.

Jeśli chcesz przywrócić wyniki do działania pierwszego, rozpoczynając działanie drugie, potrzebujesz:

startActivityForResults(myIntent, MY_REQUEST_CODE);

Wewnątrz wywoływanej aktywności możesz następnie pobrać intencję z parametru onCreate () lub użyć

getIntent();

Aby ustawić zwracanie wyniku do działania pierwszego, wykonaj w ćwiczeniu drugim

setResult(Activity.RESULT_OK, MyIntentToReturn);

Jeśli nie masz zamiaru wracać, po prostu powiedz

setResult(Activity.RESULT_OK);

Jeśli działanie ma złe wyniki, możesz użyć Activity.RESULT_CANCELED (jest to używane domyślnie). Następnie wykonujesz pierwsze ćwiczenie

onActivityResult(int requestCode, int resultCode, Intent data) {
    // Handle the logic for the requestCode, resultCode and data returned...
}

Aby zakończyć czynność drugą, użyj tych samych metod z finish (), jak opisano powyżej, z już ustawionymi wynikami.


1
„Zwróć uwagę, że zostanie uruchomiony dowolny kod po wywołaniu finish () - możesz po prostu wykonać zwrot po wywołaniu finish (), aby to naprawić” Myślę, że 'fix' to zły dobór słów. To bardziej tak, jakbyś unikał wykonywania następujących linii (nie naprawiał).
Lo-Tan

14

Po kliknięciu przycisku możesz wywołać:

super.onBackPressed();

11

jeśli używasz fragmentu, którego powinieneś użyć

getActivity().onBackPressed();

jeśli wykonujesz pojedyncze zajęcia, możesz użyć

finish();

7

wypróbuj ten kod zamiast finish:

onBackPressed();


2
Działa dobrze w przypadku powrotu z ActivityB do ActivityA. W przypadku fragmentów i pojedynczych działań można użyć odpowiedzi @Osama Ibrahim.
Eftekhari


4
Button edit = (Button) view.findViewById(R.id.yourButton);
edit.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View view) {
        Intent intent = new Intent(this, YourMainActivity.class);
        startActivity(intent);
        finish();
    }
});


4

Uważam, że Twoje drugie zajęcie prawdopodobnie nie jest powiązane z Twoim głównym zajęciem jako działalnością dziecka. Sprawdź swój AndroidManifest.xmlplik i zobacz, czy <activity>wpis dotyczący działania dziecka zawiera android:parentActivityNameatrybut. Powinien wyglądać mniej więcej tak:

<?xml ...?>
...
<activity
    android:name=".MainActivity"
    ...>
</activity>
<activity
    android:name=".ChildActivity"
    android:parentActivityName=".MainActivity"
    ...>
</activity>
...

1

Po prostu nie wzywaj finish()swojego, MainActivitya to eliminuje potrzebę Zastąpienia swojego onBackPressed()w swoim, SecondActivitychyba że robisz inne rzeczy w tej funkcji. Jeśli czujesz się na „potrzebę” tego przycisku wtedy można po prostu zadzwonić finish()na SecondActivityi że weźmie cię do MainActivitytak długo, jak nie nazwali finish()na nim


Wypróbowałem tę trasę, ale mam około 10 ekranów w kolejności, które używają plików PNG o wysokiej rozdzielczości. Problem polega na tym, że na ekranie 7 urządzenie traci pamięć z powodu wszystkich działań na stosie tylnym. Postanowiłem wywołać zakończenie każdego działania i rozwiązało to problem, zezwalając na wyrzucanie elementów bezużytecznych, ale teraz zachowanie wstecz musi zostać zakodowane ręcznie, ponieważ stos zapasowy jest teraz pusty. Czy napotkasz ten problem lub znasz jakieś mechanizmy w systemie Android, aby go rozwiązać?
Lo-Tan

Co chcesz, aby przycisk Wstecz robił? Wróć do tego, co Activitybyło poprzednie, lub zawsze wracaj do MainActivity? Ponadto, jeśli zabraknie Ci pamięci Bitmaps, przeczytaj tę część Dokumentów . Pomogło mi to
codeMagic

@ Lo-Tan, jeśli chcesz wrócić do poprzedniej czynności, myślę, że musisz wymyślić zarządzanie pamięcią dla swoich obrazów i nie kończyć działań (może za pomocą linku, który podałem). W przeciwnym razie będziesz musiał odtworzyć nową instancję działania i spróbować dowiedzieć się, do której z nich wrócić
codeMagic

Chciałbym, aby przycisk Wstecz po prostu przechodził do poprzedniego ekranu. Zasadniczo jest to seria ekranów samouczków, a użytkownik może przejść do przodu / do tyłu. Każdy ekran jest zaprojektowany i wykorzystuje wiele plików png - czasami png, które zajmują większość ekranu (nie tylko małe miniatury), więc pochłania dużo pamięci dla każdego ekranu.
Lo-Tan

@ Lo-Tan Myślę, że chcesz zastąpić metodę onBackPressed (), a następnie po prostu ręcznie utworzyć działanie, do którego chcesz przejść. Następnie możesz zakończyć ten, na którym jesteś, i uruchomić poprzedni.
Zapnologica

1

Nie wiem, czy jest to w ogóle przydatne, czy nie, ale walczyłem z tym samym problemem i znalazłem dość łatwy sposób, z tylko globalną zmienną boolowską i akcją onResume (). W moim przypadku moje działanie C, jeśli zostanie kliknięte w określony przycisk, powinno wywołać zakończenie () działania B!

Activity_A -> Activity_B -> Activity_C

Activity_A (otwiera się normalnie Activity_B)

Activity_B (kliknięcie jakiegoś przycisku otwiera Activity_C):

// Global:
boolean its_detail = false;
// -------
SharedPreferences prefs =  getApplicationContext().getSharedPreferences("sharedpreferences", 0);
boolean v = prefs.getBoolean("select_client", false);

its_detail = v;

startActivity(C);

@Override
public void onResume(){
     super.onResume();
     if(its_detail == true){
        finish();
     }
}

Tak więc za każdym razem, gdy kliknę przycisk w działaniu C, spowoduje to wykonanie funkcji „onResume ()” w działaniu B i wróci do działania A.


1
 @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        if ( id == android.R.id.home ) {
            finish();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

Wypróbuj to działa zarówno na przycisku Wstecz na pasku narzędzi, jak i na sprzęcie .


Ten pracował dla mnie. Miałem również MainActivity i SettingsActivity z android:parentActivityName=".MainActivity"drugim. Ten kod obsługuje ten przycisk Home / Back w pasku narzędzi i po prostu kończy bieżącą czynność, powracając do poprzedniej w stosie. Dzięki.
mortalis

1

Finish zamyka całą aplikację, jest to coś, czego nienawidzę w programowaniu na Androida, a nie kończę, to jest w porządku, ale nie nadążają za dobrą składnią

startActivity(intent)

Dlaczego nie

closeActivity (zamiar)?


1
Czy to odpowiada na pytanie? Czy to tylko sugestia, którą należy wypróbować? W obu przypadkach rant jest niepotrzebny i prawdopodobnie nie jest mile widziany w SO
Gilles Gouaillardet

1

Napotkaliśmy bardzo podobną sytuację.

Ćwiczenie 1 (otwarcie) -> Ćwiczenie 2 (podgląd) -> Ćwiczenie 3 (szczegóły)

Nieprawidłowa odpowiedź „na odwrocie przycisku”

  • Ponowne naciśnięcie urządzenia w działaniu 3 spowoduje również zamknięcie działania 2.

Sprawdziłem wszystkie odpowiedzi zamieszczone powyżej i żadna z nich nie zadziałała. Składnia Java do przejścia między działaniem 2 i działaniem 3 została sprawdzona pod kątem poprawności.

Nowość od kodowania przy wywoływaniu aplikacji innej firmy. przez działanie. Postanowiliśmy zbadać kąt konfiguracji - ostatecznie umożliwiając nam zidentyfikowanie pierwotnej przyczyny problemu.

Zakres : Konfiguracja działania 2 (rozmówca).

Podstawowa przyczyna :

android:launchMode="singleInstance"

Rozwiązanie :

android:launchMode="singleTask"

Najwyraźniej w tym wydaniu „on back press” singleInstance traktuje wywołane działania w jednej instancji z wywołującym Activity, podczas gdy singleTask pozwoli wywoływanym działaniom mającym swoją własną tożsamość na tyle, aby zamierzone na back pressie działały tak, jak powinny.


0
{ getApplicationContext.finish();   }

Wypróbuj tę metodę ...


Chociaż ten blok kodu może odpowiedzieć na pytanie, najlepiej byłoby, gdybyś mógł podać małe wyjaśnienie, dlaczego tak się dzieje.
David

0

możliwe, że wywołujesz finish (); w zdarzeniu przycisku kliknięcia, więc główna czynność jest zamykana zaraz po kliknięciu przycisku, a gdy wracasz z następnej czynności, aplikacja jest zamykana, ponieważ główna czynność jest już zamknięta i nie ma aktywnej aktywności.


0

na metodzie onCreate swojego działania napisz następujący kod.

getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);

Następnie zastąp wybraną metodę onOptionsItem swojego działania w następujący sposób

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()){
        case android.R.id.home:
            finish();
    }
    return super.onOptionsItemSelected(item);
}

I jesteś gotowy.


0

Musisz użyć tego w swojej MainActivity

 Intent intent = new Intent(context , yourActivity);

            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
            context.startActivity(intent);

Flaga uruchomi wiele zadań, które zachowają twoją MainActivity, gdy wywołasz zakończ, zabije inne działanie i przeniesie cię z powrotem do MainActivity

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.