Bir etkinliği geçmiş yığınından kaldırma


382

Uygulamam, kullanıcı uygulamayı ilk kez çalıştırdığında bir kayıt etkinliği gösterir.

  1. ActivitySplashScreen (oyuna hoş geldiniz, bir hesap için kaydolun mu?)
  2. ActivitySplashScreenSignUp (harika, bu bilgileri doldurun)
  3. ActivityGameMain (ana oyun ekranı)

böylece kullanıcı her bir ekrandaki düğmeyi tıkladığında, etkinlikler birbirini tam olarak bu sırada başlatır.

Kullanıcı # 2'den # 3'e kadar olan etkinliklerden gittiğinde, # 1 ve # 2 tarih yığınını tamamen silmek mümkün müdür? Kullanıcı # 3 ise ve geri düğmesine basarsa, açılış ekranına geri dönmek yerine ana ekrana giderler.

Bunu görevlerle başarabileceğimi düşünüyorum (yani # 3'te yeni bir görev başlat) ama daha basit bir yöntem olup olmadığını görmek istedim,

Teşekkürler


Ana ekranda olduktan sonra, kullanıcı uygulamanızı sürdürdüğünde onu ActivitySplashScreen veya ActivityGameMain'e götürür mü?
Tamil

Yanıtlar:


632

Bunu, dosyanızdaki ilgili girişlerde android:noHistory özniteliği olarak ayarlayarak elde edebilirsiniz . Örneğin:"true"<activity>AndroidManifest.xml

<activity
    android:name=".AnyActivity"
    android:noHistory="true" />

12
Bunu yapmanın en iyi yolu budur.
shkschneider

22
Aynı şekilde kullanabilirsiniz FLAG_ACTIVITY_NO_HISTORY.
Timmmm

34
Bunu koddan nasıl başarabilirim? Çünkü bunu her zaman yapmak istemiyorum. Belirli bir etkinliği sadece bazı koşullar altında tarihe kaldırmak istiyorum.
Namratha

8
NoHistory özniteliğini kullanmanın, örneğin G + girişinde beklenmedik davranışlara neden olabilecek bu etkinliği tamamlayacağını unutmayın. Bkz: stackoverflow.com/questions/20383878/… Uygulamam iz bırakmadan kilitlenmeye devam ederken bu hatayı bulmak için bana biraz zaman ayırdı.
Acapulco

13
Gerekli bayrağı bir bağlantı olduğu için kopyalamak zordur, bu yüzden burada kolayca kopyalanabilir. android:noHistory="true"
MirroredFate

137

Bir sonrakini başlatırken, önceki etkinliği etkinlik yığından kaldırmak için iletmeyi kullanabilirsiniz. APIDemos'ta bunun bir örneği var , ancak temelde yaptığınız tek şey aradıktan finish()hemen sonra çağırmak startActivity().


1
Merhaba Daniel, örneği okudum, ama bu sadece tarih yığınını 1 aktivite ile temizleyecek, değil mi? Yığım A, B'ye benziyorsa ve C'yi başlatıyorsam, C'nin yeni kök olmasını ve A ve B'yi tamamen temizlemesini istiyorum. Sdk örneğinde, B'den finish () çağrısı beni A yığınıyla bırakacaktı , C, değil mi? Teşekkürler.
Mark

1
B'yi başlatırken A'yı, C'yi başlatırken B'yi temizleyebilirsiniz; ancak, sanırım, eğer arzu ettiğiniz buysa, B'den A'ya geri dönemezsiniz. Bu bir sorunsa daha çok düşünmem gerekecek.
Dan Lew

3
İşaretleyin, istediğinizi elde etmek için şu bayrağı kullanmanız gerekir: FLAG_ACTIVITY_CLEAR_TOP. Umut ediyorum bu yardım eder.
Francisco Junior

3
FLAG_ACTIVITY_CLEAR_TOPC zaten arka yığınta olmadığı için çalışmaz.
Timmmm

1
@DanielLew APIDemos'ta çok fazla örnek var. Önerilen örneğin adını söyler misiniz?
Stephane

52

Evet, Intent.FLAG_ACTIVITY_NO_HISTORY'a bir göz atın .


46
Bunun, başlattığınız etkinlik için hiçbir geçmiş ayarlamadığını unutmayın. Başlattığınız etkinlikle ilgili hiçbir geçmişe sahip olmamak için, sadece android:noHistory="true"bildirimde belirledim .
georgiecasey

1
Bu iyi çalışıyor. intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)Bu bayrağı ayarlamak için düğmesini kullanın .
vovahost

1
@georgiecasey bunu bazen tarihte tutmak istediğinizde ve bazen de tarihte istemediğinizde yararlıdır.
Vihaan Verma

24

Bu muhtemelen bunu yapmak için ideal bir yol değildir. Birinin daha iyi bir yolu varsa, bunu uygulamayı dört gözle bekliyorum. İşte bu belirli görevi pre-version-11 sdk ile başardım .

açık zaman geldiğinde gitmek istediğiniz her sınıfta, bunu yapmanız gerekir:

    ... interesting code stuff ...
    Intent i = new Intent(MyActivityThatNeedsToGo.this, NextActivity.class);
    startActivityForResult(i, 0);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == R.string.unwind_stack_result_id) {
        this.setResult(R.string.unwind_stack_result_id);
        this.finish();
    }
}

o zaman yığından pop zincirini ayarlaması gereken kişinin sadece başlatmak istediğinizde bunu çağırması gerekir:

NextActivity.this.setResult(R.string.unwind_stack_result_id);
NextActivity.this.finish();

O zaman faaliyetler yığınta değil!
Dostları hatırlayın, bir aktivite başlatabilir ve daha sonra arkasından temizlemeye başlayabilirsiniz, yürütme tek bir (UI) iş parçacığını takip etmez.


Daha sonra kimse bununla karşılaşırsa, bilmenin önemli olabileceğini düşündüm, eğer ekranı döndürdüyseniz, android son etkinliği yığının dışına çıkardığınızda sizin için uygulamayı yeniden başlatacaktır. Sadece bunun farkında ol!
Travis

Bu, bir etkinliği yalnızca kullanıcının bir sonraki etkinlikte ne yaptığına bağlı olarak koşullu olarak kaldırmak istiyorsanız iyi bir yanıttır +1
TheMothaShip

23

API 11 öncesi çalışmanın bir yolu ActivityGameMainönce başlamaktır , daha sonra onCreatebu Etkinlik içinden ActivitySplashScreenetkinliğinizi başlatmaktır . ActivityGameMainEğer çok erken sıçrama için startActivity dediğimiz gibi görünmez.

Sonra yapabilirsiniz başlatırken yığını temizlemek ActivityGameMainNiyet bu bayrakları ayarlayarak:

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

Bunu ActivitySplashScreen'e de eklemelisiniz:

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

Böylece bu etkinliğe geri dönmek, ActivityGameMain .

Sana giriş ekranı ben bunu ayarlamanızı öneririz bunu başarmak için birine gitti geri, olmak istemiyorum varsayalım noHistoryGözlerinde farklı AndroidManifest.xml. Sonra goBackPressedkoduActivitySplashScreenSignUp sınıfınıza .

Ancak bunu kırmanın birkaç yolunu buldum. Bir bildirimden başka bir uygulama başlatın.ActivitySplashScreenSignUpGösterilirken ve arka geçmiş sıfırlanmazken başlatın.

Bunun tek yolu API 11'de:

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);

20

Bu şekilde kullanıyorum.

Intent i = new Intent(MyOldActivity.this, MyNewActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)
startActivity(i);

Teşekkürler. Menümde bir Ana Sayfa düğmesi olması durumunda bunu yararlı buldum ve kullanıcı oradan eve tıkladığında yığılmış etkinliklerin görünmesini istemedim.
ghitesh

8

Bu konuda geç kaldığımı biliyorum (sorunun sorulmasından bu yana iki yıl geçti) ama bunu geri düğmesine basmayı başararak başardım. Belirli etkinlikleri kontrol etmek yerine, sadece sayıya bakıyorum ve 3'ten azsa, uygulamayı arkaya gönderir (uygulamayı duraklatır ve kullanıcıyı başlatmadan önce çalışanlara geri döndürür). Üçten azını kontrol ediyorum çünkü sadece bir giriş ekranım var. Ayrıca, sayımı kontrol ediyorum çünkü uygulamam kullanıcının menü üzerinden ana ekrana geri dönmesine izin veriyor, bu yüzden yığın üzerinde giriş ekranı dışında etkinlikler varsa, bu normal gibi diğer ekranlar arasında yedekleme yapmalarına izin veriyor.

//We want the home screen to behave like the bottom of the activity stack so we do not return to the initial screen
//unless the application has been killed. Users can toggle the session mode with a menu item at all other times.
@Override
public void onBackPressed() {
    //Check the activity stack and see if it's more than two deep (initial screen and home screen)
    //If it's more than two deep, then let the app proccess the press
    ActivityManager am = (ActivityManager)this.getSystemService(Activity.ACTIVITY_SERVICE);
    List<RunningTaskInfo> tasks = am.getRunningTasks(3); //3 because we have to give it something. This is an arbitrary number
    int activityCount = tasks.get(0).numActivities;

    if (activityCount < 3)
    {
        moveTaskToBack(true);
    }
    else
    {
        super.onBackPressed();
    }
}

7

Manifest'te şunları ekleyebilirsiniz:

android:noHistory="true"

<activity
android:name=".ActivityName"
android:noHistory="true" />

Ayrıca arayabilirsiniz

finish()

startActivity'yi çağırdıktan hemen sonra (..)


2
Etkinlik bayraklarını kullanmak, bir şeyleri tezahür ettirmekten daha iyidir.
Trevor Hart

6

Sadece set noHistory="true"içinde Manifest dosyası. Aktivitenin backstack'ten kaldırılmasını sağlar.


4

Bu zarif çözümden kimsenin bahsetmediği delilik. Bu kabul edilen cevap olmalı.

SplashActivity -> AuthActivity -> DashActivity

if (!sessionManager.isLoggedIn()) {
    Intent intent = new Intent(context, AuthActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
    context.startActivity(intent);
    finish();
} else {
   Intent intent = new Intent(context, DashActivity.class);
   context.startActivity(intent);
    finish();
}

Buradaki anahtar intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); , aracı için kullanmaktır Activity. Bu orta bağlantı koptuğunda,DashActivity ilk ve son olacak.

android:noHistory="true" kötü bir çözümdür, çünkü Activity geri arama olarakonActivityResult . Bu önerilen çözümdür ve kabul edilmelidir.


1
Bu bayrak gerçek olamayacak kadar iyi geliyordu. FLAG_ACTIVITY_NO_HISTORY iyi çalışıyor ve biri yığının üstündeki bayrağıyla etkinliğe sahipken uygulamayı arka plana ve sonra tekrar ön plana koyana kadar beklendiği gibi çalışıyor. Arka plana giderken etkinlik yok edilir. Uygulamaya geri döndüğünüzde, yığındaki önceki etkinliği göreceksiniz. Kesinlikle böyle bir davranış istemedim.
NeverwinterMoon

4

Çok geç ama umarım yardımcı olur. Cevapların çoğu doğru yönü göstermiyor. Böyle bir şey için iki basit bayrak var.

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

Android dokümanlarından:

herkese açık statik final int FLAG_ACTIVITY_CLEAR_TASK API seviye 11'de eklendi

If set in an Intent passed to Context.startActivity(), this flag will cause any existing task that would be associated with the

etkinlik başlamadan önce silinecek etkinlik. Yani etkinlik, aksi takdirde boş bir görevin yeni kökü haline gelir ve eski etkinlikler tamamlanır. Bu yalnızca FLAG_ACTIVITY_NEW_TASK ile bağlantılı olarak kullanılabilir.


1

StartActivity (intent) öncesi this.finish () demeniz yeterlidir.

       Intent intent = new Intent(ActivityOne.this, ActivityTwo.class);
        this.finish();
        startActivity(intent);

"this" hatası olan kullanıcılar bunu "ActivityOne.this" olarak değiştirmelidir
ninbit

1

Geçmişten bir etkinliği kaldırma işlemi, istemediğiniz etkinlikten önce bayrağı ayarlayarak yapılır

A-> B> C> D

B ve C'yi temizlemek ve ardından bayrağı ayarlamak istiyorsanız A, B, C ve D'nin 4 Etkinlik olduğunu varsayalım.

intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

A ve B etkinliğinde

İşte kod biti

Intent intent = new Intent(this,Activity_B.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);

0
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            super.finishAndRemoveTask();
        }
        else {
            super.finish();
        }

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.