Önceki tüm etkinlikleri tamamla


368

Uygulamam aşağıdaki akış ekranlarına sahip:

Home->screen 1->screen 2->screen 3->screen 4->screen 5

Şimdi log out her ekranda ortak bir düğme var

( Home/ screen 1 / screen 2 /screen 3/ screen 4 / screen 5)

Kullanıcı oturumu kapat düğmesine (herhangi bir ekrandan) tıkladığında, tüm ekranların biteceğini ve yeni bir ekranın Log inaçılacağını istiyorum.

Bunu FLAG_ACTIVITYbaşarmak için neredeyse hepsini denedim . Ayrıca stackoverflow bazı cevaplar geçmesi, ancak sorunu çözmek mümkün değil. Uygulamam Android 1.6'da, bu yüzden kullanamıyorumFLAG_ACTIVITY_CLEAR_TASK

Sorunu çözmenin bir yolu var mı?


Yuvalanmış etkinliklerinizi startActivityForResult kullanarak çalıştırıyor musunuz?
woodshy

Tüm faaliyetler startActivity ile başlatılır.
Tanmay Mandal

Morina iç içe etkinlikte finishaffinitytask () çalıştırırken iç içe geçmiş etkinlikler kullanıyorum. davranışı değiştiriyor mu? bazen finishaffinitytask çalışırken başarısızlık sonucu ResultInfo teslim alıyorum.
Ripal Tamboli

Lütfen bu yanıtı kontrol edin, Kesinlikle size yardımcı olacaktır stackoverflow.com/a/25159180/2732632
Kimmi Dhingra

3
Android 21, Activity.finishAndRemoveTask () 'ı tanıttı.
Joseph Johnson

Yanıtlar:


543

kullanın:

Intent intent = new Intent(getApplicationContext(), Home.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Bu, evin üstündeki tüm etkinlikleri temizleyecektir.

Kullanıcı oturum açıp ana sayfa oluşturulduğunda oturum açma ekranını bitirdiğinizi varsayar ve daha sonra tüm ekranlar bunun üzerine 1'den 5'e kadar. Gönderdiğim kod sizi diğer tüm etkinlikleri bitirerek ana ekrana döndürecektir. Niyete bir ekstra ekleyebilir ve bunu ana ekran etkinliğinde okuyabilir ve bitirebilirsiniz (belki oradan bir şey veya daha sonra giriş ekranını yeniden başlatın).

Emin değilim ama bu bayrakla giriş yapmayı da deneyebilirsiniz. Bu durumda faaliyetlerin nasıl sıralanacağını bilmiyorum. Yani şu anda bulunduğunuz ekran da dahil olmak üzere ekranın altındaki olanlar temiz olup olmadığını bilmiyorum ama kesinlikle gitmek için bir yol.

Bu yardımcı olur umarım.


Kullanıcı ilk ekranını ana ekran olarak gösteriyor, ana sorun bu.
Tanmay Mandal

benim yanıtı var gibi ana ekrana geri almak ve bunu bitirmek gerekir. böylece işlem herhangi bir ekrandan yukarıdaki amacı çağırır. Ana ekranda niyeti almak ve startActivity yönteminden sonra giriş yapma ve ana ekranı bitirmek için anında bir niyet yayınlayın. Ayrıca geçişi göstermemesi için beklemedeki animasyonu içeri ve dışarı null olarak geçersiz kılabilirsiniz (bunu yapmak biraz daha hızlı hissettirdiğinden yapıyorum). yani ihtiyacınız olan şey için iyi çalışıyor olmalıdır.
DArkO

10
Etkinliği şu şekilde beyan etmek yerine , Amaç için bayrak olarak singleInstancedüşünün FLAG_ACTIVITY_CLEAR_TOP|FLAG_ACTIVITY_SINGLE_TOP. Bu, müdahale eden faaliyetleri bitirir ve istenen aktiviteyi başlatır (veya ön plana geri getirir).
CommonsWare

13
@ CommonsWare Etkinliğime eklemek intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);bana yardımcı olmadı.Anlaşılan faaliyetleri bitirmedi.Giriş ekranından geri bastığımda önceki etkinlikleri görebiliyorum Intent intent=new Intent(BaseActivity.this, Login.class);intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);startActivity(intent);.
Tanmay Mandal

26
bu kod yalnızca tüm üst düzey etkinlik yığınını temizler, intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
Ajay Venugopal

318

Deneyebilirsiniz Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK. Önceki tüm etkinlikleri tamamen temizler ve yeni etkinlik başlatır.


11
Doğru çözüm, ama sadece API 11+
riwnodennyk

Ana etkinliği gösterirken gecikmeye neden olmadığı için bu ekstra bayrağı kullandım (çok daha hızlı yeniden başlatmayacak).
Maurizio

2
@riwnodennyk neden API 11+?
Muhammed Babar

17
11 öncesi sürümler için IntentCompat.FLAG_ACTIVITY_CLEAR_TASK kullanın
Steven Pena

2
@ono Evet. Tüm ihtiyacınız olan bu olmalı. Manifestte hedef etkinliğinizin başlatma modunun "singleTask" olarak ayarlandığından emin olun.
Steven Pena

137

Yeni Etkinliğinizi başlatmadan önce aşağıdaki kodu eklemeniz yeterlidir:

finishAffinity();

Veya Android'in önceki sürümlerinde çalışmasını istiyorsanız:

ActivityCompat.finishAffinity(this);

12
ActivityCompat.finishAffinity (bu); api <16 için activity.finish () öğesini çağırır, bu yüzden çalışmaz.
Aamir Abro

1
@Beto Caldas, kaynak kodunu kendim onayladım, AamirAbro'nun belirttiği gibi API <16 için çalışmayacak. API <16 üzerinden aktardığınız etkinliği tamamlayacak.
HendraWD

39

Kullanıcı tüm açık etkinliklerden çıkmak istediğinde , uygulamanız başladığında çalışan ilk Etkinliği yükleyen bir düğmeye basmalı, diğer tüm etkinlikleri temizlemeli ve ardından kalan son etkinliğin bitmesini sağlamalıdır. Kullanıcı çıkış düğmesine bastığında aşağıdaki kodu çalıştırın. Benim durumumda, LoginActivityprogramımda çalıştırılacak ilk etkinlik.

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("EXIT", true);
startActivity(intent);

Yukarıdaki kod, dışındaki tüm etkinlikleri temizler LoginActivity. Ardından , yeniden oluşturulduğunda ve 'EXIT' sinyali iletildiğinde dinlemek için aşağıdaki kodu LoginActivity's içine koyun :onCreate(...)LoginActivity

if (getIntent().getBooleanExtra("EXIT", false)) {
    finish();  
}

Android'de bir çıkış düğmesini neden bu kadar zorlaştırıyorsunuz?

Android, kullanıcının kullandıkları programların arka planda çalışıp çalışmadığını asla umursamamasını istediği için, uygulamanızda bir "çıkış" düğmesine sahip olmanızı engellemekten kaçınmaya çalışır.

Android işletim sistemi geliştiricileri, programınızın beklenmedik bir şekilde kapanmasını ve telefonun kapanmasını sağlayabilmesini istiyor ve kullanıcı programı yeniden başlattığında kaldığı yerden devam ediyor. Böylece kullanıcı uygulamanızı kullanırken bir telefon görüşmesi alabilir ve daha fazla kaynak için uygulamanızın serbest bırakılmasını gerektiren haritaları açabilir.

Kullanıcı uygulamanızı sürdürdüğünde, kesinti olmadan kaldığı yerden devam eder. Bu çıkış düğmesi, otomatik olarak yönetilen android program yaşam döngüsüyle ilgili sorunlara neden olarak etkinlik yöneticisinden gücü gasp ediyor.


31
Intent intent = new Intent(this, classObject);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

Bu, tüm Android sürümleri için çalışacaktır. Nerede IntentCompatsınıf Android Destek kütüphanede ekledi.


IntentCompat.FLAG_ACTIVITY_CLEAR_TASKtanınmıyor, Intentyerine kullanın IntentCompat.
18:18, CoolMind

30

Etkinlik için aşağıdakileri kullanın

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);

parça kullanımı için CLEAR_TASK bayrağını kaldırın.

Umarım bu bazı insanlar için kullanılabilir.


24

Sanırım geç kaldım ama basit ve kısa bir cevap var. Etkinlik'te geçerli etkinliği ve tüm üst etkinlikleri bitirecek bir finishAffinity () yöntemi vardır, ancak yalnızca Android 4.1 veya sonraki sürümlerde çalışır.

API 16+ için şunu kullanın:

finishAffinity();

16 yaş altı için

ActivityCompat.finishAffinity(YourActivity.this);

Umarım yardımcı olur!


21

Gönderen developer.android.com :

public void finishAffinity ()

API seviye 16'ya eklendi

Bu etkinliği ve aynı afiniteye sahip geçerli görevde hemen altındaki tüm etkinlikleri bitirin. Bu genellikle bir uygulama başka bir göreve (anladığı bir içerik türünün ACTION_VIEW öğesinden) başlatılabildiğinde ve kullanıcı geçerli görevden çıkmak ve kendi görevine geçmek için yukarı gezinmeyi kullandığında kullanılır. Bu durumda, kullanıcı ikinci uygulamanın diğer etkinliklerine inerse, bunların tümü görev anahtarının bir parçası olarak orijinal görevden kaldırılmalıdır.

Bu sonlandırmanın sonuçları önceki etkinliğe iletmenize izin vermediğini ve bunu yapmaya çalışıyorsanız bir istisna atılacağını unutmayın.


19

Yan notta, bilmek güzel
Bu yanıt işe yarıyor ( https://stackoverflow.com/a/13468685/7034327 )

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
this.finish();

oysa bu işe yaramıyor

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

.setFlags() önceki bayrakların yerini alır ve yeni bayrak .addFlags()eklemez.

Bu da işe yarayacak

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

SetFlag vs addFlag arasındaki fark hakkında harika bir açıklama, teşekkür ederim
Pelanes

13

Uygulamanızda minimum sdk sürüm 16 varsa, finishAffinity () öğesini kullanabilirsiniz.

Bu etkinliği ve aynı afiniteye sahip geçerli görevde hemen altındaki tüm etkinlikleri bitirin.

Bu benim için iş Üst Ödeme ekranında tüm geri yığın etkinliklerini kaldırın,

@Override
public void onBackPressed() {
         finishAffinity();
        startActivity(new Intent(PaymentDoneActivity.this,Home.class));
    } 

http://developer.android.com/reference/android/app/Activity.html#finishAffinity%28%29


10

Bunun için uyguladığım bir çözüm (Sanırım bir yerde Stack Overflow'da buldum, ama hatırlamıyorum, bu yüzden ilk etapta bunu yapan kişi sayesinde):

Etkinliklerinizin herhangi birinden bunu yapın:

// Clear your session, remove preferences, etc.
Intent intent  = new Intent(getBaseContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Sonra LoginActivity'de ,KeyDown üzerine yazın:

public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        moveTaskToBack(true);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

3
Bu genellikle çok kötü bir fikirdir, eğer işe yarayabilirse, gelecekte kırılabilecek bir temas noktası getirir ve hata ayıklamak zor olacaktır. Sana deneyimden söylüyorum :)
Martin Marconcini

10

Uygulamanın son ekranındaki oturum kapatma düğmesi için, önceki tüm açık etkinlikleri bitirmek için oturum kapatma düğmesi dinleyicisindeki bu kodu kullanın ve sorununuz çözüldü.

{
Intent intent = new Intent(this, loginScreen.class);
ntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}

8
    Intent i1=new Intent(getApplicationContext(),StartUp_Page.class);
i1.setAction(Intent.ACTION_MAIN);
i1.addCategory(Intent.CATEGORY_HOME);
i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
i1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i1);
finish();

6
neden FLAG_ACTIVITY_CLEAR_TASK iki kez?
Choletski

1
Anladığım kadarıyla, .setFlags önceki bayrakların yerini alır ve herhangi bir bayrak eklemez. Sanırım kullanmak istediğim şey nedir? Çünkü i1.setFlags üstündeki tüm kodlar (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); silinir
iOSAndroidWindowsMobileAppsDev

addFlags Benim için çalışıyor
Jamil

1
setFlagsönceki tüm öğelerin yerini alacaktır, bu nedenle sonuncusu setFlagsgeçerlidir, önceki değiştirilir. Bu yüzden aramanıza gerek yoki1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
mtrakal

8

kullanabilirsiniz aynı sorunu var IntentCompat, böyle:

import android.support.v4.content.IntentCompat;
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);

bu kod benim için çalışıyor.

Android API 17


8

Benim durumumda aşağıdaki finishAffinity()gibi son etkinliklerde işlevi kullanıyorum :

finishAffinity()
startHomeActivity()

Umarım faydalı olur.



6

Giriş-> Ana Ekran-> Ekran 1-> Ekran 2-> Ekran 3-> Ekran 4-> Ekran 5

ekran 4'te (veya başka bir cihazda) ->

StartActivity (Giriş yap)
ile
FLAG_ACTIVITY_CLEAR_TOP


2
Geri düğmesine bastığımda, önceki tüm etkinlikler oldukları sırayla gösterilir. Kullanıcı ana ekrandan başlar.
Tanmay Mandal

6

API> = 15 ila API 23 için basit bir çözüm.

 Intent nextScreen = new Intent(currentActivity.this, MainActivity.class);
 nextScreen.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
 startActivity(nextScreen);
 ActivityCompat.finishAffinity(currentActivity.this);

Cevabınızı, herkesin bundan yararlanabilmesi için geliştirin.
Shubhamoy

5

startActivityForResult()Önceki etkinliklerinizde kullanıyorsanız , tüm etkinliklerde geçersiz kılın OnActivityResult()ve finish();içindeki yöntemi çağırın . Bu işi yapacak ...


Hayır, kullanıyorum startActivity sadece .
Tanmay Mandal

onActivityResultHer aktiviteyi sürdürmek zor olacak. DArkO'nun önerisini uyguladım ve hedefime ulaştım ve yardım için teşekkürler.
Tanmay Mandal

3

Kullanıcı oturumu kapatma düğmesine tıkladığında aşağıdaki kodu yazın:

Intent intent = new Intent(this, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Ve ayrıca giriş yaptıktan sonra yeni bir etkinlik çağırırsanız finish () kullanmayın;


2

Basitçe, giriş ekranından gittiğinizde, giriş ekranını bitirdiğinizde değil.

Ve sonra tüm ileri aktivitelerde, çıkış yapmak için bunu kullanın:

final Intent intent = new Intent(getBaseContext(), LoginScreen.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);

Mükemmel çalışıyor.


1

Kullanıcıya giriş yaparsanız screen 1ve oradan diğer ekranlara giderseniz,

Intent intent = new Intent(this, Screen1.class);
intent.addFlags(FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Geri düğmesine bastığımda, önceki tüm etkinlikler oldukları sırayla gösterilir. Bu etkinliklerin kapatılması gerekir, oturum kapatma düğmesi tıklatıldığında yığınta yalnızca bir etkinlik olur ve bu da giriş etkinliği olacaktır.
Tanmay Mandal

Bu davranışı istiyorsanız, etkinliklerinizin her birinde (oturum açma hariç) ve yukarıda gösterildiği gibi geçersiz kılmanız onKeyDownve onBackPressed(veya onKeyDownAndroid <2.0 sürümlerini desteklemek istiyorsanız) startActivity(login).
Gabriel Negut

Yığındaki tüm aktiviteleri bitirerek giriş ekranına götürecek bir düğmem var.
Tanmay Mandal

1

Bu şekilde buldum, tüm geçmişi silip çıkacak

Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
Intent intent = new Intent(getApplicationContext(), SplashScreen.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

finish();
System.exit(0);

1

Sanırım geç kaldım ama basit ve kısa bir cevap var. Etkinlik'te geçerli etkinliği ve tüm üst etkinlikleri bitirecek bir finishAffinity () yöntemi vardır, ancak yalnızca Android 4.1 veya sonraki sürümlerde çalışır.

API 16+ için şunu kullanın:

finishAffinity ();

16 yaş altı için

ActivityCompat.finishAffinity (YourActivity.this);

Umarım yardımcı olur!

shareedit 27 Mayıs 18, 8:03 yanıtladı

Akshay Taru


0

Bu çözümü API seviyesine rağmen her cihazda çalışmak için buldum (<11 için bile)

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
ComponentName cn = intent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(cn);
startActivity(mainIntent);

0

Önceki tüm etkinlikleri kapatmanın ve belleği temizlemenin en iyi yolu

finishAffinity()
System.exit(0);

0
startActivity(
                Intent(this, LoginActivity::class.java)
                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    .addFlags(FLAG_ACTIVITY_CLEAR_TASK)
            )
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.