Jak zapobiec powrotowi do poprzedniej aktywności?

210

Po naciśnięciu przycisku BACK na telefonie chcę uniemożliwić powrót określonej aktywności do poprzedniej.

W szczególności mam ekrany logowania i rejestracji, oba rozpoczynają nowe działanie, nazywane HomeScreenpo pomyślnym zalogowaniu / rejestracji. Po uruchomieniu HomeScreen chcę uniemożliwić użytkownikom powrót do ekranu logowania lub rejestracji po naciśnięciu przycisku BACK.

Próbowałem używać Intent.FLAG_ACTIVITY_NO_HISTORY, ale ponieważ aplikacja ma integrację z Facebookiem, kiedy używane jest „Logowanie za pomocą Facebooka”, Facebook powinien powrócić do początkowego ekranu logowania, dlatego powinienem przechowywać historię tych działań.

Myślałem o zastąpieniu zachowania przycisku BACK, HomeScreenaby bezpośrednio zakończyć aplikację, gdy przycisk jest wciśnięty i użyłem

@Override
public void onBackPressed() {
    finish();
}

ale to też nie działa.

ecem
źródło
1
Żeby to wyjaśnić, próbujesz odzyskać zachowanie każdego z wyjątkiem Facebooka?
havexz
2
W pewnym sensie tak, ale tak naprawdę to, czego chcę, to po pomyślnym zalogowaniu i otwarciu HomeScreen użytkownik nie powinien mieć możliwości powrotu do ekranu logowania przez naciśnięcie przycisku BACK. Podobnie jak na przykład Twitter lub Foursquare, po zalogowaniu się do tych aplikacji nie widzimy strony logowania, dopóki się nie wylogujemy (nawet jeśli po zalogowaniu naciśniemy WSTECZ).
ekem

Odpowiedzi:

345

Moją sugestią byłoby zakończenie działania, do którego użytkownicy nie chcą wracać. Na przykład w swojej aktywności związanej z logowaniem, zaraz po połączeniu startActivityzadzwoń finish(). Gdy użytkownicy klikną przycisk Wstecz, nie będą mogli przejść do czynności logowania, ponieważ została ona zabita ze stosu.

koder
źródło
2
Co jeśli chciałbym, aby wątek z poprzedniego działania nadal działał?
AlleyOOP
2
Nie chciałbyś wtedy stosować mojego podejścia. Wywołanie zakończenia () spowoduje zabicie aktywności. Czy możesz rozpocząć proces, który chcesz uruchomić w ramach działania, które zamierzasz?
koder
7
Uwaga: jeśli zadzwonisz finishpodczas wspólnego przejścia, możesz uzyskać krwawienie z poprzedniej czynności. na przykład, jeśli masz HomeActivity-> IntermediateActivity-> FinalActivityi wywołać finish()w IntermediateActivitynatychmiast po uruchomieniu FinalActivityzobaczysz HomeActivityza chwilę krótki.
David Murdoch,
101

Poniższe rozwiązanie może być bardzo przydatne w zwykłym scenariuszu logowania / głównej aktywności lub implementacji ekranu blokowania.

Aby zminimalizować aplikację zamiast wracać do poprzedniej aktywności, możesz zastąpić ją onBackPressed()następująco:

@Override
public void onBackPressed() {
    moveTaskToBack(true);
}

moveTaskToBack(boolean nonRoot)pozostawia tylny stos bez zmian, po prostu umieszcza zadanie (wszystkie działania) w tle. To samo, jakby użytkownik nacisnął przycisk Home .

Parametr boolean nonRoot- Jeśli false, działa to tylko wtedy, gdy działanie jest głównym zadaniem; jeśli true, będzie działać dla dowolnej aktywności w zadaniu.

Marcel Bro
źródło
3
Idealny do ekranu logowania, ponieważ utrzymuje nienaruszoną historię.
Hackmodford
Dziękuję, próbowałem to znaleźć przez około trzy dni. Z powodu Androida: flaga noHistory = „true” dla działania nie działa zgodnie z oczekiwaniami (flaga noHistory odtwarza aktywność po zminimalizowaniu) i metoda wykończenia () czasami nie działa dla mnie, ale dlaczego nadal nie rozumiem.
Denshov,
37

Nie jestem pewien, czego dokładnie chcesz, ale wygląda na to, że powinno to być możliwe, a także brzmi, jakbyś już był na dobrej drodze.

Oto kilka linków, które mogą pomóc:

Wyłącz przycisk Wstecz w Androidzie

  MyActivity.java =>
    @Override
    public void onBackPressed() {

       return;
    }

Jak mogę wyłączyć „powrót” do niektórych działań?

  AndroidManifest.xml =>
<activity android:name=".SplashActivity" android:noHistory="true"/>
paulsm4
źródło
1
Nie mogę użyć opcji noHistory z powodu problemu z Facebookiem, który próbowałem wyjaśnić w swoim pytaniu, a także jednym z komentarzy. Ale rzecz z przyciskiem WSTECZ nie wyłącza go, ale powoduje, że opuszcza całą aplikację tak jak System.exit(0)się nazywa (wiem, że nie jest to najlepsza praktyka, ale chciałem tylko podać przykład).
ecem
Dzięki, działało świetnie. Jedyne sugestie, które tu przedstawię, to brak potrzeby powrotu. Po prostu usuń super.onBackPressed () i pozostaw metodę pustą. To też działa dobrze
hyperCoder
20

W twoim przypadku istnieją dwa rozwiązania: działanie A rozpoczyna działanie B, ale nie chcesz wracać do działania A w działaniu B.

1. Usunięto poprzednie działanie A z tylnego stosu.

    Intent intent = new Intent(activityA.this, activityB.class);
    startActivity(intent);
    finish(); // Destroy activity A and not exist in Back stack

2. Wyłączone działanie przycisku cofania w działaniu B.

Istnieją dwa sposoby zapobiegania zdarzeniu wstecznemu, jak poniżej:

1) Poleć podejście

@Override
public void onBackPressed() {
}

2) Zastąp metodę onKeyDown

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if(keyCode==KeyEvent.KEYCODE_BACK) {
        return false;
    }
    return super.onKeyDown(keyCode, event);
}

Mam nadzieję, że jest to przydatne, ale nadal zależy od twoich sytuacji.

Luna Kong
źródło
3
Czy wyłączenie funkcji onBackPressed () nie jest złe?
C. Skjerdal
Zależy to całkowicie od tego, co próbujesz zrobić, w funkcji aplikacji potrzebuje tego, a następnie idź.
user3099225
To niesamowite, jak zupełnie zapomniałem o pierwszej metodzie finish(). Niepotrzebnie przemyślane za pomocą nohistoryatrybutu, flag intencji, tagów manifestu aktywności rodzica itp.! Głupie, dzięki za odpowiedź!
varun
8

Ponieważ zaproponowano już wiele świetnych rozwiązań, źle postaram się podać bardziej szczegółowe wyjaśnienia.

Jak pominąć powrót do poprzedniej aktywności?

Usuń poprzednią aktywność z Backstack. Prosty

Jak usunąć poprzednią aktywność z Backstack?

Połączenie finish()Metoda

Normalny przepływ:

wprowadź opis zdjęcia tutaj
Wszystkie działania są przechowywane w stosie znanym jako Backstack.
Kiedy zaczynasz nową aktywność ( startActivity(...)), nowa aktywność jest wypychana na górę stosu, a po naciśnięciu przycisku Wstecz aktywność jest wyskakująca ze stosu.
Jednym z najważniejszych zadań należy zauważyć, że gdy przycisk jest wciśnięty, a następnie z powrotemfinish(); metoda nazywa się wewnętrznie. Jest to domyślne zachowanie metody onBackPressed ().

Więc jeśli chcesz pominąć Aktywność B?

tj. A <--- C

Po prostu dodaj finish();metodę po swoim startActvity(...)w ćwiczeniu B

Intent i = new Intent(this, C.class);
startActivity(i);
finish();

wprowadź opis zdjęcia tutaj

Rohit Singh
źródło
6

finish()daje metodę zamknięcia bieżącej działalności, a nie całej aplikacji. I lepiej nie próbuj szukać metod zabijania aplikacji. Mała rada.

Czy próbowałeś koniunktury Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_NO_HISTORY? Pamiętaj, aby używać tych flag podczas Intentrozpoczynania aktywności!

Cadavre
źródło
2
FLAG_ACTIVITY_NO_HISTORYuniemożliwia mojemu LoginScreen przechwytywanie oddzwaniania Facebooka, gdy używane jest logowanie przez Facebook. Ponieważ gdy fokus zniknie z ekranu logowania, nie można go wznowić (ponieważ nie ma historii). Ale nie próbowałem tego Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS, sprawdzę to, dzięki!
ecem
również dzięki tej finish()metodzie, nie wiedziałem o tym.
ecem
4

Umieść finish()zaraz po

Intent i = new Intent(Summary1.this,MainActivity.class);
            startActivity(i);
finish();
Param Trivedi
źródło
1
Jest to w zasadzie to, co powiedziała zaakceptowana odpowiedź sprzed czterech lat.
TylerH
3

Odpowiedź paulsm4 jest poprawna. Jeśli onBackPressed()po prostu wrócisz, spowoduje to wyłączenie przycisku Wstecz. Jednak myślę, że lepszym podejściem, biorąc pod uwagę twój przypadek użycia, jest odwrócenie logiki aktywności, tj. Uczynienie aktywności domowej główną, sprawdzenie, czy użytkownik jest tam zalogowany, jeśli nie, rozpoczęcie aktywności logowania. Powodem jest to, że jeśli zastąpisz przycisk Wstecz w głównej aktywności, większość użytkowników będzie zdezorientowana, gdy go odepchnie, a aplikacja nic nie zrobi.

skarbie
źródło
3

Ta metoda działa dobrze

Intent intent = new Intent(Profile.this, MainActivity.class); 
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(intent);
pulak
źródło
2

Po prostu zastąp metodę onKeyDown i sprawdź, czy został naciśnięty przycisk Wstecz.

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) 
{
    if (keyCode == KeyEvent.KEYCODE_BACK) 
    {
        //Back buttons was pressed, do whatever logic you want
    }

    return false;
}
Plemię Maszyn
źródło
1
@Override
public void onBackPressed() {
}

Po utworzeniu onBackPressed()wystarczy usunąć super.onBackPressed();i to powinno działać

hyperCoder
źródło
1

Położyć

finish();

natychmiast po ActivityStart, aby zatrzymać aktywność uniemożliwiającą powrót do niej. Następnie dodaj

onCreate(){
    getActionBar().setDisplayHomeAsUpEnabled(false);
    ...
}

do aktywności, którą zaczynasz.

Brandon Dyer
źródło