Android: Arka yığını temizleme


330

Android'de bazı aktivitelerim var, diyelim A, B, C.

A'da, B açmak için bu kodu kullanın:

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

B, C açmak için bu kodu kullanın:

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

Kullanıcı C'de bir düğmeye dokunduğunda, A'ya geri dönmek ve arka yığını temizlemek istiyorum (hem B hem de C'yi kapatın). Böylece kullanıcı geri düğmesini B ve C kullandığında görünmez, aşağıdakileri deniyorum:

Intent intent = new Intent(this, A.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
startActivity(intent);

Ancak A aktivitesine geri döndüğümde geri düğmesini kullanırsam B ve C hala görünmeye devam ediyor.

Yanıtlar:


438

Aşağıdakiler FLAG_ACTIVITY_NEW_TASKiçin dokümanlarda açıklandığı gibi eklemeyi deneyin FLAG_ACTIVITY_CLEAR_TOP:

Bu başlatma modu ayrıca FLAG_ACTIVITY_NEW_TASK ile birlikte iyi bir etki yaratmak için de kullanılabilir: bir görevin kök etkinliğini başlatmak için kullanılırsa, o görevin o anda çalışan herhangi bir örneğini ön plana getirecek ve ardından kök durumuna temizleyecektir. Bu, özellikle bildirim yöneticisinden bir etkinlik başlatırken özellikle kullanışlıdır.

Başlamak için kodunuz A:

Intent intent = new Intent(this, A.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(intent);
CurrentActivity.this.finish(); // if the activity running has it's own context


// view.getContext().finish() for fragments etc.

28
Teşekkürler ama bunu denedim. Yine C'yi gösterdikten sonra geri düğmesine dokunduğumda. Ne eksik olabilirim?
Martin

4
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
dzeikei

8
benim için çalışmıyor ancak kaynak etkinliğinde bitirmek () çağırmak elde etmek için ne gerekiyorsa yapar
2cupsOfTech

10
Bu aynı işe yaramadı aynı sorun vardı. Benim için sabit olan, yeni etkinliğe başladıktan sonra finish ()
Arno

20
Ayrıca bir tane daha net niyet ekledim = new Intent (SingUpActivity.this, LoginActivity.class); intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity (niyet); bitiş();
Sam

147
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

8
CLEAR_TOPBayrağa tüm saygıyla - bu kombinasyon, tüm yığını tamamen temizleyen ve yeni etkinliği uygulamadaki tek etkinlik haline getiren SADECE kombinasyonudur. Teşekkür ederim!
Aviel Gross

8
Bu ve kabul edilen cevap arasındaki fark nedir?
Yuri Heupa

7
Teşekkürler, kabul edilen cevapla farkı, bu bayrakla aktivite çağırmamıza gerek olmamasıdır.
Finish

1
FLAG_ACTIVITY_CLEAR_TASK NEW_TASK ile mükemmel bir şekilde çalıştı
Shamsul Arefin Sajib

1
Bu kabul edilen cevap olmalı. Çok teşekkür ederim.
Danimarkalı Danimarka Ansari

77

İlgili etkinlik için manifests dosyası eklemeye ne dersiniz:

android:noHistory="true"

B ve C'nin aktivite tanımına? Backstack'e eklenmeyecekler. İstediğiniz bu olup olmadığından emin değilim.


3
Bunu kullanırken çok dikkatli olun - FB veya benzer bir işlevsellik ile giriş kullanıyorsanız
Skynet

2
@Skynet Neden? Bunu yapmayla ilgili sorunlar nelerdir?
Alfie Woodland

8
Gerçek olmayan bir sayfadan giriş yapmak için FB'ye kontrolü geçtiğinizde, FB uygulaması artık kullanıcıyı kaybettikten sonra nereye inecek değil, benim durumumda telefon ana ekranına dönüyordu ve neredeyse işimi kaybettim!
Skynet

Bu bir aktivitenin backstack'e eklenmesine izin vermez .... bu doğru bir çözüm değildir.
Tarun

Tam olarak arıyorum
Masum

63

Bu beni uzun süre rahatsız ediyor. Sonunda bunu yaparak çalıştım:

Parça halinde şunları kullanın:

Intent intent = new Intent(view.getContext(), A.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(intent);

Etkinlik'te şunu kullanın ( Intent.FLAG_ACTIVITY_CLEAR_TASKparçaya kıyasla bir niyet bayrağı daha ekleyin ):

Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

1
Androidannotations kullanıyorsanız şunları eklemelisiniz: Intent.FLAG_ACTIVITY_CLEAR_TASK
yosafatade

Etkinlik solutioin benim için iyi çalıştı. Her ne kadar API 16 ile Daniel Schuler'in çözümü daha kolay olduğunu düşünüyorum.
PhilippS

Teşekkürler yosafatade, eksik olan buydu!
Marty Miller

30
  1. Ekle android:launchMode="singleTop"Etkinlik A için Manifest'inizde etkinlik elemana
  2. Ardından , Etkinlik A'yı başlatırken intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) ve intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

Bu, Etkinlik A başlatıldığında üstündeki tüm görevlerin A'nın üstte olacağı şekilde temizlendiği anlamına gelir. Kökte A ile yeni bir arka yığın oluşturulur ve kullanmak, singleTopA'yı yalnızca bir kez başlatmanızı sağlar (çünkü A nedeniyle şu anda en üsttedir ..._CLEAR_TOP).


3
Evet. şu an kullandığım bu ama bunu yapmıyor. Geri düğmesine bastığımda hala C görünüyor.
Martin

Tuhaf, bunu bir projede kullandım ve iyi çalışıyor ... geri basmak beni ana ekrana götürüyor. Belki de başka bir şey oluyor. Manifestinizi gönderebilir misiniz?
Joseph Earl

Emülatörü yeniden başlattım ve şimdi söylediğiniz gibi çalışıyor gibi görünüyor. Yardımın için çok teşekkürler!
Martin

singleTop'un yığını temizlemesiyle ilgisi yoktur.
stdout

29

API 16'dan (Jelly Bean) başlayarak arayabilirsiniz finishAffinity().

Artık ActivityCompat.finishAffinity(Activity activity)uyumluluk kitaplığıyla da arayabilirsiniz .

Manifest'te taskAffinity öğesini, bu etkinlik grubuna özgü bir paket adına ayarladığınızdan emin olun.

Daha fazla bilgi için bakın:
http://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#finishAffinity%28android.app.Activity%29


API 16 ile uyumluysanız gerçekten kullanıcı dostu ve kolay bir çözüm.
PhilippS

3
hatırlatma: Bu yalnızca aynı görevi paylaşan etkinlikler için çalışırAfinity name
Ryan

bu yalnızca tarihte yalnızca bir etkinliğiniz varsa işe yarar.
arsent

17

Kullanmayı deneyin

intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

ve yok

intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

11

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



8

İleride yapılacak araştırmalar için bu kodu deneyin.

Intent intent = new Intent(context, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();

Bu bayraklar sonunda benim için çalıştı. Yaptığım şey, bu bayraklarla ve aynı bir boole ekstra EXIT = true ile içinde bulunduğum aynı Etkinliğe başladım. İnCreate () in EXIT için başlatma parametrelerini kontrol ettim ve true olarak ayarlanmışsa finish () olarak adlandırdım. Bu sadece kendi uygulamanızı kapatmak için çok fazla zorluk.
Janne Oksanen

8

FinishAffinity () kullanın; backstack etkinliklerini temizlemek için A görevini başlatırken C görevinde.


sadece bu cevap benim için çalışıyor. Niyet.FLAG_ACTIVITY_CLEAR_TOP ve Niyet.FLAG_ACTIVITY_NEW_TASK gerekli değildir
nuttynibbles

7

Yeni bir Etkinlik başlatmak ve diğer tüm etkinlik yığınlarını veya arka yığınlarını kapatmak veya yok etmek için bu kodu kullanın.

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

5
Use finishAffinity() to clear all backstack with existing one.

Suppose, Activities A, B and C are in stack, and finishAffinity(); is called in Activity C, 

    - Activity B will be finished / removing from stack.
    - Activity A will be finished / removing from stack.
    - Activity C will finished / removing from stack.

5

Yardımcı olabilecek ilginç bir çözüm buldum. Bunu onBackPressed()yöntemimde yaptım .

finishAffinity();
finish();

FinishAffinityvarolan etkinliğin yığına bağlantısını kaldırır. Ve sonra bitir bu etkinlikten çıkmanıza yardımcı olur. Hangi sonunda uygulamadan çıkacak.


4

Orijinal sorudaki kodun benim için iyi çalıştığı için burada cevapları biraz yanıltıcı buldum?

A kök aktivite olduğunda, yalnızca FLAG_ACTIVITY_CLEAR_TOP ile B veya C'den başlatmak B ve C'yi arka yığından kaldırır.


4

Kotlin'de neredeyse java ile aynı. Sadece | sembolü veya metin ile değiştirilir . Yani, şöyle yazılmıştır-

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)

3

Tüm çözümleri denedim ve hiçbiri benim için ayrı çalışmadı. Benim Çözümüm:

Bildirmek Activity Aolarak SingleTopkullanılarak[android:launchMode="singleTop"] Android manifest.

Şimdi Aher yerden başlatırken aşağıdaki bayrakları ekleyin . Yığını temizler.

Intent in = new Intent(mContext, A.class);
in.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK );
startActivity(in);
finish();

2

Intent.FLAG_ACTIVITY_CLEAR_TOPbu durumda çalışmaz. Lütfen kullan(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)

Daha fazla ayrıntı için lütfen bu belgelere bakın.


2

Eğer başlamak gerekir gibi bana geliyor Activity Cdan Activity Bkullanarak startActivityForResult(). Bir düğmeyi tıklattığınızda Activity C, arayın setResult(RESULT_OK)ve finish()böylece Activity Csonlandırılır. 'De Activity B, onActivityResult()yanıtı da çağırarak yanıt verebilirsiniz finish()ve sonra geri alınırsınız Activity A.


7
Evet, ancak A ve C arasında 42 etkinlik varsa, bu oldukça sıkıcı olacaktır. FLAG_ACTIVITY_CLEAR_TOP bayrağının doğrudan OP'nin istediklerini yapması gerekiyor.
Guillaume Brunerie

Bu, OP'nin istediklerini elde etmenin en iyi yoludur ve @Guillaume'un dediği gibi, kök ile yığının üst kısmı arasındaki tüm etkinliklerde kod gerektirir.
Jake Basile

Tam olarak not edildi. Bunlar görünüşe göre öğrenmem gereken bayraklar.
Maximus

1

logout.addFlags (Intent.FLAG_ACTIVITY_CLEAR_TASK); logout.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK);


1

Adresinizi aramak için bu örneği kullanabilirsiniz Activity A.Activity C

Intent loout = new Intent(context, LoginActivity.class); loout.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); context.startActivity(loout);


1

benim için eklemek Intent.FLAG_ACTIVITY_CLEAR_TASKsorunu çözdü

Intent i = new Intent(SettingsActivity.this, StartPage.class);
                i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP  | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(i);
finish();

1

Gelişmiş, Yeniden Kullanılabilir Kotlin:

Bayrağı doğrudan ayarlayıcı yöntemini kullanarak ayarlayabilirsiniz. KOTLIN yılında orise yedek Java bitwise veya için |.

intent.flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK

Bunu bir kereden fazla kullanırsanız, bir Intent uzantısı işlevi oluşturun

fun Intent.clearStack() {
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}

Ardından, amacı başlatmadan önce doğrudan bu işlevi çağırabilirsiniz

intent.clearStack()

Başka durumlarda ek bayrak ekleme seçeneğine ihtiyacınız varsa, uzantı işlevine isteğe bağlı bir param ekleyin.

fun Intent.clearStack(additionalFlags: Int = 0) {
    flags = additionalFlags or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}

0

Ayrıca FLAG_ACTIVITY_CLEAR_TOP, eklemeyi Intent.FLAG_ACTIVITY_SINGLE_TOPde deneyebilirsiniz :

intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);


Bu, yığının kökünü değil, yalnızca yığının üstündeki etkinliği etkiler.
Jake Basile

0

Verilen kod düzgün çalışıyor. Uygulama Yaşam Döngüsü örneğinde denedim.

FLAG_ACTIVITY_CLEAR_TOP bayrağıyla A etkinliğine başladıktan sonra arka yığında B ve C yok.


0

activity_name.this.finish()yeni niyet başladıktan sonra aradım ve benim için çalıştı.

I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"

Ama benim için işe yaramayacak ... Bu çözümü kullanmak için önermiyorum ama bayrak ayarını sizin için işe yaramazsa bunu deneyebilirsiniz. Ama yine de kullanmamanızı tavsiye ederim


0

Niyete NO History Flag ekleyin.

B aktivitesinde, C aktivitesini aşağıdaki gibi başlatın >>>>>>

Intent intent = new Intent(this, C.class);
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NO_HISTORY); 
startActivity(intent);
finish();

0

Manifest'te

android:launchMode="singleTask"

ve

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

0

Ya bu Apple Şifre Activity BveActivity C

android:noHistory="true"

veya Override onBackPresseda ile geri basmayı önlemek için işlev return.

@Override
public void onBackPressed() {
   return;
}

0

Net geri tarafı için kullanın SetFlags () yöntemi tüm etkinlik yakın açtı ve başlangıç yourActvity

Intent intent = new Intent(getApplicationContext(), yourActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
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.