Android: Önceki tüm etkinlikleri arka yığından kaldır


119

Profil Etkinliğimde Oturumu Kapat düğmesine tıkladığımda, kullanıcıyı yeni kimlik bilgilerini kullanması gereken Oturum Açma sayfasına götürmek istiyorum .

Bu nedenle bu kodu kullandım:

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

içinde onButtonClickOturumu Kapat düğmesinin.

Ancak sorun, Oturum Açma Etkinliğinde cihaz geri düğmesine tıkladığımda beni ProfileActivity'ye götürüyor. LoginActivity'de cihaz geri düğmesine bastığımda uygulamanın kapanmasını bekliyordum.

Neyi yanlış yapıyorum?

LoginActivityandroid:launchMode="singleTop" için bildirimde de ekledim

Teşekkür ederim


@GauravVashisth Bu çözümü takip
ediyordum

@ abbas.aniefa Bu çözüm biraz karmaşık. Tüm arka yığını temizlemenin tek yolu bu mu? Çünkü 30+ Aktivitem var, bu yüzden hepsi için bu yayın kodunu
yazmalıyım

daha sonra bunu deneyin, stackoverflow.com/questions/10961481/… . Yayını kullanmak daha iyi bir çözümdür.
abbas.aniefa

Oturumu kapatmak için kullanabileceğiniz başka bir yaklaşım, oturumu kapattığınızda, paylaşılan tercihlerde bir bayrak depoladığınızda ve bir etkinliğin her onRestart () yönteminde bu değişken değerini kontrol edebilirsiniz, eğer true olarak ayarlanmışsa, mevcut etkinliği bitirebilirsiniz. bu yüzden arka planda kaç etkinlik açık olursa olsun. bu tüm aktivitenizi bitirirdi.
Hiren Dabhi

Orijinal kodunuz aslında bir ince ayar ile API seviyesi 11 veya üstü için çalışır. intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
İşaretleri

Yanıtlar:


304

Burada önerilen çözüm benim için çalıştı:

Java

Intent i = new Intent(OldActivity.this, NewActivity.class);
// set the new task and clear flags
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);

Kotlin

val i = Intent(this, NewActivity::class.java)
// set the new task and clear flags
i.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(i)

Ancak, API seviyesi> = 11 gerektirir.


Beyler, belgelerini okuyun. FLAG_ACTIVITY_CLEAR_TASKBu, almanın resmi yoludur. Uygulamadaki tüm etkinlikleri değiştirmenize gerek yok.
AlikElzin-kilaka


MinAPI = 16 değerim var, bu yüzden bu benim için mükemmel çalışıyor. Ancak, görünüm yürütmesinin API> 21 ile biraz yavaş ve API'ler <21 ile sorunsuz olduğunu fark ettim. Aynı sorunu yaşayan var mı?
Red M

1
Bu, aktiviteler için yeni bir Görev yaratacak
Rohit

@kgiannakakis Şüphesiz çözüm tek bir görevimiz varsa (Activity Back stack) çalışıyor, ancak birden fazla görevimiz (Activity stack) olduğunda çalışmıyor. Örneğin, A, B, C ve D uygulamam için dört etkinliğim olduğunu varsayalım. A-> B-> C (arka plan) ve D-> A-> B (Ön plan) ve Eğer ben Şu anki yığınımdan (D-> A-> B) aktivite A'yı, niyet filtresiyle ne olacağını önerdin ne olacağını mevcut yığınımı temizle (D-> A-> B) ve A aktivitesini aç ve geri bastığımda kapat ancak son uygulama düğmesine basarsam, orada Uygulamamın iki arka yığınını görebilirim.
Rahul Pareta

31

Oturum kapatma düğmesini kullandığınızda tüm uygulamanızın etkinliklerini temizlemenin bir çözümü.

Bir Aktivite başlattığınız her seferinde, şu şekilde başlayın:

Intent myIntent = new Intent(getBaseContext(), YourNewActivity.class);
startActivityForResult(myIntent, 0);

Tüm uygulamayı kapatmak istediğinizde şunu yapın:

setResult(RESULT_CLOSE_ALL);
finish();

RESULT_CLOSE_ALL, tüm etkinlikleri kapatmak istediğinizi işaret etmek için benzersiz bir tam sayıya sahip son bir genel değişkendir.

Ardından, her etkinliğin onActivityResult(...)geri çağrısını tanımlayın, böylece bir etkinlik RESULT_CLOSE_ALL değeriyle geri döndüğünde, finish()şunları da çağırır :

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch(resultCode)
    {
    case RESULT_CLOSE_ALL:
        setResult(RESULT_CLOSE_ALL);
        finish();
    }
    super.onActivityResult(requestCode, resultCode, data);
}

Bu, tüm faaliyetlerinizi kapatan kademeli bir etkiye neden olacaktır.

Ancak bu bir hack'tir ve kullanılmak startActivityForResultüzere tasarlanmamış bir şekilde kullanır .

Belki de bunu yapmanın daha iyi bir yolu, burada gösterildiği gibi yayın alıcılarını kullanmak olabilir:

Oturumu kapattığınızda, "geri" düğmesinin yalnızca oturum açılmış Etkinlikleri açmasını önleyerek Etkinlik geçmişi yığınını temizleyin

Diğer yöntemler için de şu konu başlıklarına bakın:

Android: Arka yığını temizleyin

Önceki tüm aktiviteleri tamamlayın


4
Tarihte yaklaşık 30 etkinliğiniz olduğunda bu mümkün müdür?
Rakesh Gondaliya

4
olmalı. Ancak tarihte 30 etkinliğiniz varsa, tasarımınızı değiştirmeyi düşünebilirsiniz. 30 biraz fazla görünüyor ve Android onları kendi kendine öldürebilir.
Anup Cowkur

1
Bu, bunu yapmanın kötü bir yolu gibi görünüyor. @RakeshGondaliya 'nın cevap sorusu yasal görünüyor. 30 belki sadece 'yüksek' sayıda faaliyeti temsil eden bir sayı. Bu cevap daha iyi görünüyor: stackoverflow.com/a/3008684/243709
Aman Alam

Bu cevap harika. Ayrıca, etkinliklerinize backstack'te etkinlikler göndermek için EventBus kitaplığını da kullanabilirsiniz. github.com/greenrobot/EventBus
Stan

Kullanım basit ile 'Intent.FLAG_ACTIVITY_CLEAR_TOP' bayrak Better niyet
Naveen Rao

18

Etkinlik yığınını tamamen temizlemek için TaskStackBuilder'ı kullanarak yeni bir görev yığını oluşturmak istersiniz, örneğin:

Intent loginIntent = LoginActivity.getIntent(context);
TaskStackBuilder.create(context).addNextIntentWithParentStack(loginIntent).startActivities();

Bu sadece yeni, temiz bir görev yığını oluşturmakla kalmaz, aynı zamanda LoginActivity'nizin bir üst etkinliği varsa "yukarı" düğmesinin düzgün çalışmasına da izin verir.


1
Bunu yapmanın en iyi yolu budur.
Paul Burke

FLAG_ACTIVITY_NEW_TASKya finishAffinity()da benim için çalışmadı. Sadece bu cevap amacı çözdü.
TM

Uygulamayı geri düğmesi ile terk edersem ve uygulama simgesiyle geri dönersem, bu yöntemi çağırdığım aktivitede açılır. Yani benim için çalışmıyor.
Tgo1014

17

finishAffinity()API 16'da eklendi. ActivityCompat.finishAffinity()Önceki sürümlerde kullanın . Niyet kullanarak herhangi bir etkinliği başlatıp mevcut etkinliği bitirdiğinizde. Şimdi ActivityCompat.finishAffinity()bunun yerine kullanın finish(). mevcut aktivitenin altındaki tüm yığılmış aktiviteyi bitirecektir. Benim için iyi çalışıyor.


3
AslındaActivityCompat.finishAffinity()
The Berga

finishAffinity()aynı yakınlığın arka yığınında bulunan tüm etkinliklerle de geçerli etkinliği bitirir.
Neeraj Sewani

10

Benim için ne işe yaradı

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

5

Size önerebileceğim olası bir çözüm, ProfileActivity'mandroid:launchMode="singleTop" için manifest'i eklemektir . ve oturumu kapat tıklandığında, Oturum Açma Etkinliğini yeniden başlatarak oturumu kapatabilirsiniz. çıkışta bunu arayabilirsin.

Intent in = new Intent(Profile.this,Login.class);
                in.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(in);
                finish();

Bunu yaptım, olan şey şuydu: geri düğmesine tıkladığımda beni ProfileActivity'ye
geldiğim yerden Activty'ye götürüyor

Bu olabilir çünkü u, finish () 'yi çağırarak değil, yeni bir amaç çağırarak ProfileActivity'ye geldi; LoginActivty dışındaki diğer etkinliklerden ProfileActivity'ye nasıl geliyorsunuz?
Android

Ben de aynı soruyu geçiyorum. Memroy eksikliğinden dolayı Login amacı sistem tarafından yok edildiğinde işe yaramayacağını düşünüyorum.
user1914692

5

API 11+ için şu şekilde kullanabilirsiniz Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK:

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

Önceki tüm aktiviteleri tamamen temizler ve yeni aktivite başlatır.


4

Deneyebilirsiniz finishAffinity(), tüm mevcut etkinlikleri kapatır ve Android 4.1 üzerinde ve üzerinde çalışır.


1
API 16'da finishAffinity () eklendi. Önceki sürümde ActivityCompat.finishAffinity () kullanın. Benim için iyi çalışıyorum.
Anurag Srivastava

2

Ben de aynı sorunla karşı karşıyayım ..

giriş etkinliğinde yaptığım şey.

    Intent myIntent = new Intent(MainActivity.this, ActivityLoggedIn.class);
    finish();
    MainActivity.this.startActivity(myIntent);  

çıkışta

   Intent myIntent = new Intent(ActivityLoggedIn.this, MainActivity.class);
   finish();
   ActivityLoggedIn.this.startActivity(myIntent);

Bu iyi çalışıyor ancak ActivityLoggedIn içindeyken ve uygulamayı küçülttüğümde ve uygulama çekmecesinde başlatıcı düğmesi simgesine tıkladığımda MainActivity yeniden başlıyor: - / bayrağı kullanıyorum

android:LaunchMode:singleTask 

MainActivity için.


2

Aşağıdakileri kullanın activity

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.


1

Sadece tut

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

4
Çalışmıyor. Yine de geri düğmesini kullanarak ProfileActivity'ye gidebilirim
Archie.bpgc

1

Amaç işaretlerinin hiçbiri benim için işe yaramadı, ancak bunu şu şekilde düzelttim:

Bir kullanıcı bir aktiviteden çıkış yaptığında, o aktiviteden bir mesaj yayınlamak zorunda kaldım, daha sonra bitirmek istediğim aktivitelerde aldım ve ardından finish (); ve oldukça iyi çalışıyor.


1

Bunu deneyin, işe yarayacak:

Intent logout_intent = new Intent(DashboardActivity.this, LoginActivity.class);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(logout_intent);
finish();

1

API düzeyi 11 veya üzerinde, tüm etkinlik yığınını temizlemek için Intent'i kullanın FLAG_ACTIVITY_CLEAR_TASKve FLAG_ACTIVITY_NEW_TASKişaretleyin.

Intent i = new Intent(OldActivity.this, NewActivity.class);
// set the new task and clear flags
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |  Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(i);

0

Bunu kullan

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

setFlags ve addFlags'i biliyor muydunuz?
GvSharma


0

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 = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK

Bunu düzenli olarak kullanmayı planlıyorsanız, bir Amaç uzantısı işlevi oluşturun

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

Amacı başlatmadan önce bu işlevi doğrudan çağırabilirsiniz

intent.clearStack()

Diğer durumlarda ek işaretler ekleme seçeneğine ihtiyacınız varsa, uzantı işlevine isteğe bağlı bir parametre ekleyin.

fun Intent.clearStack(additionalFlags: Int = 0) {
    flags = additionalFlags or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.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.