Android: Bersihkan tumpukan belakang

330

Di Android saya punya beberapa aktivitas, misalkan A, B, C.

Di A, saya menggunakan kode ini untuk membuka B:

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

Di B, saya menggunakan kode ini untuk membuka C:

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

Ketika pengguna mengetuk tombol di C, saya ingin kembali ke A dan menghapus tumpukan kembali (tutup B dan C). Jadi ketika pengguna menggunakan tombol kembali B dan C tidak akan muncul, saya sudah mencoba yang berikut:

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

Tetapi B dan C masih muncul jika saya menggunakan tombol kembali ketika saya kembali beraktivitas A. Bagaimana saya bisa menghindari ini?

Martin
sumber

Jawaban:

438

Coba tambahkan FLAG_ACTIVITY_NEW_TASKseperti yang dijelaskan dalam dokumen untuk FLAG_ACTIVITY_CLEAR_TOP:

Mode peluncuran ini juga dapat digunakan untuk efek yang baik dalam hubungannya dengan FLAG_ACTIVITY_NEW_TASK: jika digunakan untuk memulai aktivitas root dari suatu tugas, itu akan membawa setiap instance yang sedang berjalan dari tugas itu ke latar depan, dan kemudian menghapusnya ke status root. Ini sangat berguna, misalnya, ketika meluncurkan aktivitas dari manajer notifikasi.

Jadi kode Anda untuk diluncurkan Aadalah:

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.
Jake Basile
sumber
28
Terima kasih tetapi saya sudah mencoba ini. Masih ketika saya mengetuk tombol kembali setelah itu menunjukkan C lagi. Apa yang bisa saya lewatkan?
Martin
4
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
dzeikei
8
tidak bekerja untuk saya, tetapi memanggil selesai () pada aktivitas sumber melakukan apa yang saya perlu capai
2cupsOfTech
10
Saya memiliki masalah yang sama bahwa ini tidak berhasil. Apa yang diperbaiki bagi saya adalah memanggil finish () setelah memulai aktivitas baru
Arno
20
Saya juga menambahkan satu lagi Intent intent = = Intent baru (SingUpActivity.this, LoginActivity.class); intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity (niat); selesai();
Sam
147
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
diesel
sumber
8
Dengan segala hormat pada CLEAR_TOPbendera - kombinasi ini adalah HANYA yang sepenuhnya membersihkan seluruh tumpukan dan menjadikan aktivitas baru satu-satunya di aplikasi. Terima kasih!
Aviel Gross
8
Apa perbedaan antara ini dan jawaban yang diterima?
Yuri Heupa
7
Terima kasih, perbedaan dengan jawaban yang diterima adalah bahwa dengan bendera ini kita tidak perlu memanggil activity.finish
Pablo Cegarra
1
FLAG_ACTIVITY_CLEAR_TASK bekerja dengan sempurna bersama NEW_TASK
Shamsul Arefin Sajib
1
Ini harus menjadi jawaban yang diterima. Terima kasih banyak.
MD Danish Ansari
77

Bagaimana dengan menambahkan file manifes untuk aktivitas terkait:

android:noHistory="true"

ke definisi aktivitas B dan C? Mereka tidak akan ditambahkan ke backstack. Tidak yakin apakah itu yang Anda inginkan.

Dominik Helleberg
sumber
3
Berhati-hatilah saat menggunakan ini - Jika Anda menggunakan login dengan FB atau fungsionalitas serupa lainnya
Skynet
2
@ Skynet Mengapa? Apa masalah yang terkait dengan melakukan ini?
Alfie Woodland
8
Ketika Anda memberikan kontrol ke FB untuk masuk dari sebuah halaman dengan nohistory sebagai benar, aplikasi FB tidak sekarang mendarat di mana setelah masuk pengguna, dalam kasus saya itu kembali ke layar beranda ponsel dan saya hampir kehilangan pekerjaan saya!
Skynet
Ini tidak membiarkan aktivitas ditambahkan ke backstack .... ini bukan solusi yang benar.
Tarun
Persis yang saya cari
Masum
63

Ini mengganggu saya untuk waktu yang lama. Akhirnya saya mengatasinya dengan melakukan ini:

Dalam fragmen, gunakan:

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

Di Aktivitas, gunakan (tambahkan satu bendera maksud lebih banyak Intent.FLAG_ACTIVITY_CLEAR_TASKdibandingkan dengan fragmen):

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);
Geng Jiawen
sumber
1
Jika Anda menggunakan androidannotations, Anda harus menambahkan: Intent.FLAG_ACTIVITY_CLEAR_TASK
yosafatade
Aktivitas solutioin bekerja dengan baik untuk saya. Meskipun saya pikir dengan API 16 solusi dari Daniel Schuler lebih mudah.
Philipps
Terima kasih yosafatade, itulah yang saya lewatkan!
Marty Miller
30
  1. Tambahkan android:launchMode="singleTop"ke elemen aktivitas di manifes Anda untuk Aktivitas A
  2. Kemudian gunakan intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) dan intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)ketika memulai Aktivitas A

Ini berarti bahwa ketika Kegiatan A diluncurkan, semua tugas di atasnya dibersihkan sehingga A berada di atas. Back stack baru dibuat dengan A di root, dan menggunakan singleTopmemastikan Anda hanya pernah meluncurkan A sekali (karena A sekarang di atas karena ..._CLEAR_TOP).

Joseph Earl
sumber
3
Iya. inilah yang saya gunakan sekarang tetapi itu tidak berhasil. Masih C muncul ketika saya menekan tombol kembali.
Martin
Aneh, saya menggunakannya dalam sebuah proyek dan berfungsi dengan baik ... menekan kembali membawa saya ke layar beranda. Mungkin ada hal lain yang terjadi. Bisakah Anda memposting manifes Anda?
Joseph Earl
Saya me-restart emulator dan sekarang tampaknya berfungsi seperti yang Anda katakan. Terima kasih banyak atas bantuan Anda!
Martin
singleTop seharusnya tidak ada hubungannya dengan membersihkan tumpukan.
stdout
29

Mulai di API 16 (Jelly Bean), Anda bisa menelepon finishAffinity() .

Sekarang Anda juga bisa menelepon ActivityCompat.finishAffinity(Activity activity) dengan perpustakaan kompatibilitas.

Pastikan untuk menetapkan taskAffinity di manifes ke nama paket yang unik untuk grup aktivitas tersebut.

Lihat untuk info lebih lanjut:
http://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#finishAffinity%28android.app.Activity%29

Daniel Schuler
sumber
Solusi yang benar-benar userful dan mudah jika Anda membaca di API 16. Bekerja untuk saya!
Philipps
3
pengingat: ini hanya akan berfungsi untuk kegiatan yang berbagi nama taskAffinity yang sama
Ryan
ini hanya berfungsi jika Anda hanya memiliki satu aktivitas dalam sejarah.
arsen
17

Coba gunakan

intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

dan tidak

intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
Muhammad Aamir Ali
sumber
11

Jika aplikasi Anda memiliki minimum sdk versi 16 maka Anda dapat menggunakan finishAffinity ()

Selesaikan aktivitas ini dan juga semua aktivitas tepat di bawahnya dalam tugas saat ini yang memiliki afinitas yang sama.

Ini berfungsi untuk saya. Di layar Pembayaran Top, hapus semua aktivitas back-stack,

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

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

Jaydeep purohit
sumber
9

Sesuai Wakka dalam Menghapus aktivitas dari tumpukan riwayat ...


Tambahkan android:noHistory="true"atribut ke Anda <activity>di AndroidManifest.xmlseperti ini:

    <activity android:name=".MyActivity"
        android:noHistory="true">
    </activity>
Richard Le Mesurier
sumber
8

Untuk penelitian selanjutnya, coba kode ini.

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();
GeetT
sumber
Bendera ini akhirnya bekerja untuk saya. Apa yang saya lakukan adalah saya memulai Kegiatan yang sama dengan bendera-bendera ini dan EXIT boolean ekstra = true. Di dalam onCreate () saya memeriksa parameter peluncuran untuk EXIT dan disebut selesai () jika disetel benar. Itu banyak kerumitan hanya untuk menutup aplikasi Anda sendiri.
Janne Oksanen
8

Gunakan finishAffinity (); dalam tugas C saat memulai tugas A untuk menghapus aktivitas backstack.

baswaraj
sumber
hanya jawaban ini yang bekerja untuk saya. Intent.FLAG_ACTIVITY_CLEAR_TOP dan Intent.FLAG_ACTIVITY_NEW_TASK tidak diperlukan
nuttynibbles
7

Gunakan kode ini untuk memulai Kegiatan baru dan tutup atau hancurkan semua tumpukan atau tumpukan aktivitas lainnya.

Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
Pankaj Talaviya
sumber
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.
Firzan Shaikh
sumber
5

Saya menemukan solusi menarik yang mungkin bisa membantu. Saya melakukan ini dalam onBackPressed()metode saya .

finishAffinity();
finish();

FinishAffinitymenghapus koneksi aktivitas yang ada ke tumpukannya. Dan kemudian selesai membantu Anda keluar dari aktivitas itu. Yang pada akhirnya akan keluar dari aplikasi.

Sujith Royal
sumber
4

Saya menemukan jawabannya di sini agak menyesatkan karena kode dalam pertanyaan awal tampaknya berfungsi dengan baik untuk saya?

Dengan A sebagai aktivitas root, memulainya dari B atau C hanya dengan FLAG_ACTIVITY_CLEAR_TOP menghapus B dan C dari tumpukan belakang.

Ianjoyner
sumber
4

Di kotlin hampir sama dengan java. Hanya | simbol diganti oleh atau teks. Jadi, ada tertulis seperti-

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
Exigente05
sumber
3

Saya mencoba semua solusi dan tidak ada yang bekerja secara individual untuk saya. Solusi saya adalah:

Nyatakan Activity Asebagai SingleTopdengan menggunakan [android:launchMode="singleTop"]manifes Android.

Sekarang tambahkan flag berikut saat meluncurkan Adari mana saja. Ini akan menghapus tumpukan.

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();
Tarun
sumber
2

Intent.FLAG_ACTIVITY_CLEAR_TOPtidak akan berfungsi dalam kasus ini. Mohon gunakan(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)

Untuk detail lebih lanjut silakan lihat dokumentasi ini .

Ashish Saini
sumber
2

Kedengarannya seperti Anda perlu mulai Activity Cdari Activity Bdengan menggunakan startActivityForResult(). Ketika Anda mengklik tombol di Activity C, panggilan setResult(RESULT_OK)dan finish()jadi Activity Cberakhir. Di Activity B, Anda dapat onActivityResult()membalasnya dengan memanggilnya finish()sendiri, dan Anda akan dibawa kembali ke sana Activity A.

Maximus
sumber
7
Ya, tetapi jika ada 42 aktivitas antara A dan C, ini akan agak membosankan. Bendera FLAG_ACTIVITY_CLEAR_TOP seharusnya melakukan langsung apa yang diinginkan OP.
Guillaume Brunerie
Ini akan menjadi cara yang kurang optimal untuk mencapai apa yang diinginkan OP, dan seperti yang dikatakan @Guillaume, itu akan membutuhkan kode dalam semua aktivitas antara root dan bagian atas tumpukan.
Jake Basile
Sepatutnya dicatat. Ini adalah bendera yang perlu saya pelajari tentang rupanya.
Maximus
1

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

Abhijeet
sumber
1

Anda dapat menggunakan contoh ini untuk menelepon Activity Adari AndaActivity C

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

Vipin Yadav
sumber
1

bagi saya menambahkan Intent.FLAG_ACTIVITY_CLEAR_TASKmemecahkan masalah

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();
Mohamed Mo'nes
sumber
1

Lanjutan, Kotlin yang Dapat Digunakan Kembali:

Anda dapat mengatur bendera secara langsung menggunakan metode penyetel. Di Kotlin oradalah pengganti untuk bitwise Java atau |.

intent.flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK

Jika menggunakan ini lebih dari sekali, buat fungsi ekstensi Intent

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

Anda kemudian dapat langsung memanggil fungsi ini sebelum memulai niat

intent.clearStack()

Jika Anda memerlukan opsi untuk menambahkan flag tambahan dalam situasi lain, tambahkan param opsional ke fungsi ekstensi.

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

Selain itu FLAG_ACTIVITY_CLEAR_TOP, Anda dapat mencoba menambahkan Intent.FLAG_ACTIVITY_SINGLE_TOPjuga:

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

james
sumber
Itu hanya akan memengaruhi aktivitas di bagian atas tumpukan, bukan root.
Jake Basile
0

Kode yang diberikan bekerja dengan benar. Saya telah mencoba sampel Aplikasi Life Cycle.

Saya tidak mendapatkan B dan C di tumpukan belakang setelah memulai aktivitas A dengan flag, FLAG_ACTIVITY_CLEAR_TOP

Sathesh
sumber
0

saya menelepon activity_name.this.finish()setelah memulai niat baru dan itu berhasil untuk saya.

I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"

Tapi itu tidak akan bekerja untuk saya ... Saya tidak menyarankan solusi ini untuk digunakan tetapi jika pengaturan flag tidak akan bekerja untuk Anda daripada Anda dapat mencoba ini .. Tapi tetap saya sarankan jangan menggunakannya

Tukar-iOS-Android
sumber
0

Tambahkan NO History Tandai dalam maksudnya.

Di aktivitas B, mulailah aktivitas C seperti di bawah >>>>>>

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

Dalam manifes

android:launchMode="singleTask"

dan

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
selikuran
sumber
0

Tambahkan ini ke Activity BdanActivity C

android:noHistory="true"

atau Override onBackPressedfungsi untuk menghindari kembali menekan dengan a return.

@Override
public void onBackPressed() {
   return;
}
Renjith JR
sumber
0

Gunakan metode setFlags () untuk membersihkan sisi belakang membuka semua aktivitas tutup dan mulai aktivitas Anda

Intent intent = new Intent(getApplicationContext(), yourActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
Pankaj Talaviya
sumber