Android: Etkinlik Yığını Temizle


132

Başvurumda birkaç faaliyetim var. ve akış çok karmaşıktır. Çıkış uygulamasına tıkladığımda Giriş Ekranına gider ve oradan kullanıcı iptal butonu ile çıkış yapabilir (arama system.exit(0))

Çıkış veya geri düğmesinden çıktığımda, sistem yığından bir etkinlik başlatır :( Giriş ekranına ulaştığımda yığındaki tüm etkinlikleri nasıl temizleyebilirim? finish()Çok fazla etkinlik olduğundan ve bazı etkinliklerin kapatılmaması gerektiğinden arama pratik değildir. yerel kamera çağırma etkinliği gibi aktiftirler.

validateuser logoutuser = new validateuser();
logoutuser.logOut();
Intent loginscreen = new Intent(homepage.this, Login2.class);
(homepage.this).finish();
loginscreen.setFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(loginscreen);


Yanıtlar:


339

Çoğunuz yanılıyorsunuz. Var olan etkinlik yığınını, içinde ne olduğuna bakılmaksızın kapatmak ve yeni kök oluşturmak istiyorsanız, doğru bayrak kümesi aşağıdaki gibidir:

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

Dokümandan :

public static final int FLAG_ACTIVITY_CLEAR_TASK
API seviyesi 11'e eklendi

Hedefe iletilen bir Amaç içinde ayarlanırsa Context.startActivity(), bu bayrak, etkinlik başlatılmadan önce etkinlikle ilişkilendirilecek tüm mevcut görevlerin temizlenmesine neden olur. Diğer bir deyişle, etkinlik, normalde boş olan bir görevin yeni kökü haline gelir ve tüm eski etkinlikler tamamlanır. Bu yalnızca ile bağlantılı olarak kullanılabilir FLAG_ACTIVITY_NEW_TASK.


Mükemmel çalıştı. Teşekkürler. Garip bir şekilde minSDK = 9 ile hata vermedi.
Mahm00d

Açıkçası bu işlevi hiç kullanmadım, çarpışmadan sonra diriltmedim ve daha çok
çökmeye

Aynı işlev IntentCompat.makeRestartActivityTask, destek kitaplığından da sağlanır.
sealskej

Yalnızca bu iki işaretin eklenmesi, etkinlik yığını izini geride bırakır (bir öncekinin üstünde başlar), ardından uygulamayı yeniden başlatan ve ardından tamamen çıkan Intent.FLAG_ACTIVITY_CLEAR_TOP eklendi. Açıkça etkinliklere herhangi bir işaret eklemedim tho. Sorun ne olabilir?
Farid

1
En iyi başlangıçlardan biri: "Çoğunuz yanılıyorsunuz."
nibbana

31

Aradığınızda startActivityson aktivitesi üzerine her zaman kullanabilirsiniz

Intent.FLAG_ACTIVITY_CLEAR_TOP

bu niyet üzerinde bir bayrak olarak.

Burada bayrak hakkında daha fazla bilgi edinin .


bu da yardımcı olmuyor. Ben sadece bitiş tarihi () ile bitmeyen bir aktivite getiriyorum; :(
Jay Mayu

Sanırım FLAG_ACTIVITY_CLEAR_TOP, üstteki etkinlikleri temizliyor. Benim sorunum alttaki etkinlikler :(
Jay Mayu

Sanırım akışın gerçekte nasıl olduğuna bağlı. Burada daha fazla bilgi okumalısınız: developer.android.com/reference/android/content/… ve developer.android.com/guide/topics/fundamentals/…
David Olsson

7
Doğru kaynakları gösterdiğiniz için teşekkürler. yaptığım hata Giriş etkinliğini kapatmaktı. Kapatmamalıyım. Etkinlik ilk yüklendiğinde. bu yüzden Clear_top bayrağını kullanarak geri çağırdığımda, giriş etkinliği üstteki tüm etkinlikleri temizler. oturum açma ilk giriş etkinliği olduğundan, daha sonra başlatılan tüm etkinlikleri temizler. bu yüzden bingo işe yaradı :)
Jay Mayu

13
Belgelerden, FLAG_ACTIVITY_CLEAR_TOP yığını yalnızca belirli etkinlik "mevcut görevde zaten çalışıyor" ise temizler
AlikElzin-kilaka

16

API düzeyi 4'ten mevcut sürüm 17'ye kadar çalışan yeni en önemli etkinlik olarak yeni bir etkinlik başlatmak için basit bir yardımcı yöntem:

static void startNewMainActivity(Activity currentActivity, Class<? extends Activity> newTopActivityClass) {
    Intent intent = new Intent(currentActivity, newTopActivityClass);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
        intent.addFlags(0x8000); // equal to Intent.FLAG_ACTIVITY_CLEAR_TASK which is only available from API level 11
    currentActivity.startActivity(intent);
}

şu anki etkinliğinizden şöyle seslenin:

startNewMainActivity(this, MainActivity.class);

1
Her zaman olduğu kadar sadece intent.addFlags (0x8000) kullanamaz mısınız; ve bunu basitleştirmek?
Davor

Bu bayrak ilk olarak Honeycomb'da tanıtıldığından, önceki sürümlerde ne gibi bir etkiye sahip olabileceği hakkında hiçbir fikrim yok. Yani, bu benim tedbirli davranmamdı. Ama sanırım şartın kaldırılması sorun olmamalı.
Temmuz'13

1
API seviyesi 11'in altında olduğunda bu bayrağı eklemek istiyorsanız, yapmanız gereken Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMBbaşka bir şey intent.addFlags(0x8000);asla eklenmeyecek
Straw Hat

Kullanıcıya niyetler yoluyla birçok aktiviteyi art arda yaptırıyorum. Uygulamanın yığında çok fazla etkinlikle çökmediğinden emin olmak için herhangi bir şey yapmam gerekir mi? Teşekkürler!
Ruchir Baronia

9

Etkinlik Arka Durumunu aşağıdaki kodla temizleyin :

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

Bitti


Kullanıcıya niyetler yoluyla birçok aktiviteyi art arda yaptırıyorum. Uygulamanın yığında çok fazla etkinlikle çökmediğinden emin olmak için herhangi bir şey yapmam gerekir mi? Teşekkürler!
Ruchir Baronia

@RuchirBaronia, A -> B -> C -> D -> E -> F -> G -> H'ye giderseniz, şimdi H -> Kodumu Son Aktivite olacağımdan daha sonra yazarsınız sonra Geri tuşuna basın Uygulama arka eyaletler etkinliği olmadığından kapanacak, bunun size yardımcı olacağını umuyoruz.
Hiren Patel

Bunu yapmam gerekiyor mu? Aktivite yığınını asla temizlemesem ne olur?
Ruchir Baronia

@RuchirBaronia, Backpress: H -> G -> F -> E -> D -> C -> B -> A
Hiren Patel

Ancak bir süre yeni etkinliği ararken beyaz ekran gösteriyor. Bunu nasıl çözeceksin?
Sagar

4

Benim durumumda, LoginActivity de kapatıldı. Sonuç olarak,

Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK

Yardım etmedi.

Ancak, ayar

Intent.FLAG_ACTIVITY_NEW_TASK

bana yardımcı oldu.


Kullanıcıya niyetler yoluyla birçok aktiviteyi art arda yaptırıyorum. Uygulamanın yığında çok fazla etkinlikle çökmediğinden emin olmak için herhangi bir şey yapmam gerekir mi? Teşekkürler!
Ruchir Baronia

3
Intent intent = new Intent(LoginActivity.this, Home.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);  //It is use to finish current activity
startActivity(intent);
this.finish();

1
Neden hem kullandığınız this.finish()ve setFlags()ayrıca geçerli aktiviteyi temizlemek için?
Sagar

3

Güvenmeyen bir çözüm istediğinizi not ettim finish() , ancak bunun yine de yardımcı olup olmayacağını merak ediyorum.

Tüm uygulama ömrü boyunca ayakta kalan bir statik sınıf değişkeniyle bir çıkış bayrağının yükseltilip yükseltilmediğini izledim. Her bir ilgili aktivitede onResume()kullanın

@Override
public void onResume() {
    super.onResume();
    if (ExitHelper.isExitFlagRaised) {
        this.finish();
    }
}

ExitHelper sınıfı

public class ExitHelper {
    public static boolean isExitFlagRaised = false;
}

Diyelim ki mainActivity'de, bir kullanıcı çıkmak için bir düğmeye basar - bunu ayarlayabilir ExitHelper.isExitFlagRaised = true;ve sonra yapabilirsiniz finish(). Daha sonra, otomatik olarak devam ettirilen diğer ilgili faaliyetler de bitecektir.


kodu MainActivity onresume () 'de kullanırsam ve ardından backpress'teki 2. etkinlikten ana etkinliğe geri dönersem ne olur
Mithu

3

Bu karar gayet iyi çalışıyor:

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

Ancak yeni etkinlik uzun süre başlar ve bir süre beyaz ekran görürsünüz. Bu kritikse, şu geçici çözümü kullanın:

public class BaseActivity extends AppCompatActivity {

    private static final String ACTION_FINISH = "action_finish";

    private BroadcastReceiver finisBroadcastReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        registerReceiver(finisBroadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                finish();
            }
        }, new IntentFilter(ACTION_FINISH));
    }

    public void clearBackStack() {
        sendBroadcast(new Intent(ACTION_FINISH));
    }

    @Override
    protected void onDestroy() {
        unregisterReceiver(finisBroadcastReceiver);
        super.onDestroy();
    }
}

Nasıl kullanılır:

public class ActivityA extends BaseActivity {

    // Click any button
    public void startActivityB() {
        startActivity(new Intent(this, ActivityB.class));
        clearBackStack();
    }
}

Dezavantaj: yığın üzerinde kapatılması gereken tüm etkinlikler BaseActivity'yi genişletmelidir


2

Xamarin Geliştiricileri için şunları kullanabilirsiniz:

intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearTask);

1

Kotlin Kullanımı:

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

0

Amaç amacı = yeni Amaç (LoginActivity.this, MainActivity.class); intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); startActivity (niyet); bitiş();

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.