Android: Hapus semua aktivitas sebelumnya dari back-stack

119

Ketika saya mengklik tombol Logout di Aktivitas Profil saya, saya ingin mengarahkan pengguna ke halaman Login , di mana dia perlu menggunakan kredensial baru.

Karenanya saya menggunakan kode ini:

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

di bagian onButtonClicktombol Logout.

Tetapi masalahnya adalah ketika saya mengklik tombol kembali perangkat pada Aktivitas Login, saya akan dibawa ke ProfileActivity. Saya mengharapkan aplikasi harus ditutup ketika saya menekan tombol kembali perangkat di LoginActivity.

Apa yang saya lakukan salah?

Saya juga menambahkan android:launchMode="singleTop"dalam manifes untuk LoginActivity saya

Terima kasih

Archie.bpgc
sumber
@GauravVashisth Saya baru saja mengikuti solusi ini stackoverflow.com/questions/5794506/…
Archie.bpgc
@ abbas.aniefa Solusi itu agak ribet. Apakah itu satu-satunya cara untuk menghapus semua back stack. Karena saya memiliki 30+ Aktivitas jadi saya harus menulis kode siaran ini untuk semuanya
Archie.bpgc
coba ini, stackoverflow.com/questions/10961481/… . Menggunakan Broadcast adalah solusi yang lebih baik.
abbas.aniefa
pendekatan lain yang bisa Anda gunakan untuk keluar, setelah Anda keluar, simpan satu tanda di sharedpreferences dan di setiap metode onRestart () dari aktivitas Anda bisa memeriksa nilai variabel ini jika disetel ke true, Anda bisa menyelesaikan aktivitas saat ini. jadi tidak peduli berapa banyak aktivitas yang terbuka di latar belakang. ini akan menyelesaikan semua aktivitas Anda.
Hiren Dabhi
Kode asli Anda sebenarnya berfungsi untuk API level 11 atau lebih tinggi dengan perubahan. Anda hanya perlu menyatukan semua bendera dalam satu panggilan: intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);Saya mendapat jawaban dari pertanyaan ini: stackoverflow.com/questions/3473168/…
jokeefe

Jawaban:

304

Solusi yang diusulkan di sini berhasil untuk saya:

Jawa

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)

Namun, ini membutuhkan API level> = 11.

kgiannakakis
sumber
Guys, baca dokumentasi FLAG_ACTIVITY_CLEAR_TASK. Ini adalah cara resmi untuk mendapatkannya. Tidak perlu mengubah semua aktivitas di aplikasi.
AlikElzin-kilaka
Ini tidak berfungsi untuk pemberitahuan stackoverflow.com/questions/24873131/…
Sam
Saya memiliki minAPI = 16 saya, jadi ini berfungsi dengan baik untuk saya. Namun, saya perhatikan bahwa eksekusi tampilan agak lamban dengan API> 21 dan lancar dengan API <21. Ada yang mengalami masalah yang sama?
Red M
1
Ini akan membuat Tugas baru untuk aktivitas
Rohit
@kgiannakakis Tidak diragukan lagi, solusi bekerja jika kita hanya memiliki satu tugas (Activity Back stack) tetapi ketika kita memiliki banyak tugas (Activity stack) itu tidak berfungsi. ex- katakanlah saya memiliki empat aktivitas untuk aplikasi saya A, B, C & D. Misalkan saya memiliki dua Aktivitas back stack A-> B-> C (latar belakang) & D-> A-> B (Foreground) dan If I panggil aktivitas A dari tumpukan saya saat ini (D-> A-> B) dengan filter maksud apa yang Anda sarankan apa yang akan terjadi itu bersihkan tumpukan saya saat ini (D-> A-> B) dan buka aktivitas A dan ketika saya tekan kembali tutup aplikasi tetapi jika saya menekan tombol aplikasi baru-baru ini, saya dapat melihat dua tumpukan belakang Aplikasi saya di sana.
Rahul Pareta
31

Berikut ini salah satu solusi untuk menghapus semua aktivitas aplikasi Anda saat Anda menggunakan tombol logout.

Setiap kali Anda memulai sebuah Aktivitas, mulailah seperti ini:

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

Saat Anda ingin menutup seluruh aplikasi, lakukan ini:

setResult(RESULT_CLOSE_ALL);
finish();

RESULT_CLOSE_ALL adalah variabel global terakhir dengan bilangan bulat unik untuk memberi sinyal bahwa Anda ingin menutup semua aktivitas.

Kemudian tentukan onActivityResult(...)callback setiap aktivitas sehingga ketika aktivitas kembali dengan nilai RESULT_CLOSE_ALL, itu juga memanggil finish():

@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);
}

Ini akan menyebabkan efek kaskade yang menutup semua aktivitas Anda.

Namun ini adalah hack dan digunakan startActivityForResultdengan cara yang tidak dirancang untuk digunakan.

Mungkin cara yang lebih baik untuk melakukan ini adalah menggunakan penerima siaran seperti yang ditunjukkan di sini:

Saat keluar, hapus tumpukan Riwayat aktivitas, mencegah tombol "kembali" dari membuka Aktivitas khusus masuk

Lihat utas ini untuk metode lain juga:

Android: Hapus tumpukan belakang

Selesaikan semua aktivitas sebelumnya

Anup Cowkur
sumber
4
Apakah layak jika Anda memiliki sekitar 30 aktivitas dalam sejarah ??
Rakesh Gondaliya
4
seharusnya. Tetapi jika Anda memiliki 30 aktivitas dalam sejarah, Anda mungkin ingin mempertimbangkan untuk mengubah desain Anda. 30 sepertinya terlalu berlebihan dan Android mungkin akan membunuhnya sendiri.
Anup Cowkur
1
Ini tampaknya cara yang buruk untuk melakukannya. Pertanyaan jawaban @RakeshGondaliya tampaknya sah. 30 mungkin hanya angka yang mewakili sejumlah aktivitas 'tinggi'. Jawaban ini terlihat lebih baik: stackoverflow.com/a/3008684/243709
Aman Alam
Jawaban ini bagus. Anda juga dapat menggunakan perpustakaan EventBus untuk mengirim acara ke aktivitas Anda di backstack. github.com/greenrobot/EventBus
Stan
Lebih baik menggunakan bendera 'Intent.FLAG_ACTIVITY_CLEAR_TOP' sederhana dengan maksud
Naveen Rao
18

Untuk menghapus tumpukan aktivitas sepenuhnya, Anda ingin membuat tumpukan tugas baru menggunakan TaskStackBuilder, misalnya:

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

Ini tidak hanya akan membuat tumpukan tugas baru dan bersih, ini juga akan memungkinkan berfungsinya tombol "naik" jika LoginActivity Anda memiliki aktivitas induk.

Matt Accola
sumber
1
Ini cara terbaik untuk melakukannya.
Paul Burke
FLAG_ACTIVITY_NEW_TASKatau finishAffinity()tidak berhasil untuk saya. Hanya jawaban ini yang menyelesaikan tujuannya.
TM
Jika saya meninggalkan aplikasi melalui tombol kembali dan kembali melalui ikon aplikasi, itu terbuka dalam aktivitas yang saya sebut metode itu. Jadi tidak bekerja untukku.
Tgo1014
17

finishAffinity()ditambahkan di API 16. Gunakan ActivityCompat.finishAffinity()di versi sebelumnya. Kapan Anda akan meluncurkan aktivitas apa pun menggunakan maksud dan menyelesaikan aktivitas saat ini. Sekarang gunakan ActivityCompat.finishAffinity()saja finish(). itu akan menyelesaikan semua aktivitas bertumpuk di bawah aktivitas saat ini. Ini bekerja dengan baik untuk saya.

Anurag Srivastava
sumber
3
Ini sebenarnyaActivityCompat.finishAffinity()
The Berga
finishAffinity()juga menyelesaikan aktivitas saat ini dengan semua aktivitas yang ada di back-stack dari afinitas yang sama.
Neeraj Sewani
10

Apa yang berhasil untuk saya

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

Salah satu solusi yang mungkin saya sarankan untuk Anda adalah menambahkan android:launchMode="singleTop"manifes untuk ProfileActivity saya . dan ketika log out diklik Anda dapat logoff mulai lagi Anda LoginActivity. saat logout, Anda dapat menyebutnya.

Intent in = new Intent(Profile.this,Login.class);
                in.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(in);
                finish();
Android
sumber
Saya melakukan ini, yang terjadi adalah: ketika saya mengklik tombol kembali, saya dibawa ke Activty dari mana saya datang ke
ProfileActivity
Ini mungkin terjadi karena u datang ke ProfileActivity dengan memanggil maksud baru bukan dengan memanggil finish (); Bagaimana Anda masuk ke ProfileActivity dari aktivitas lain selain dari LoginActivty?
Android
Saya melewati pertanyaan yang sama. Saya pikir itu tidak akan berfungsi ketika maksud Login dihancurkan oleh sistem, katakanlah karena kurangnya memroy.
pengguna1914692
5

Untuk API 11+ Anda dapat menggunakan Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASKseperti ini:

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

Itu benar-benar akan menghapus semua aktivitas sebelumnya dan memulai aktivitas baru.

orang gila
sumber
4

Anda dapat mencoba finishAffinity(), itu menutup semua aktivitas saat ini dan bekerja pada dan di atas Android 4.1

Kelinci
sumber
1
finishAffinity () ditambahkan di API 16. Gunakan ActivityCompat.finishAffinity () di versi sebelumnya. Saya bekerja dengan baik untuk saya.
Anurag Srivastava
2

Saya juga menghadapi masalah yang sama ..

dalam aktivitas login yang saya lakukan adalah.

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

saat keluar

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

Ini berfungsi dengan baik tetapi ketika saya berada di ActivityLoggedIn dan saya meminimalkan aplikasi dan mengklik ikon tombol peluncur di laci aplikasi, MainActivity dimulai lagi: - / saya menggunakan bendera

android:LaunchMode:singleTask 

untuk MainActivity.

Sujal Mandal
sumber
2

Gunakan yang berikut ini untuk activity

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

hapus tanda CLEAR_TASK untuk penggunaan fragmen.

Saya harap ini mungkin berguna bagi sebagian orang.

Aristo Michael
sumber
1

Simpan saja

Intent intent = new Intent(ProfileActivity.this,
    LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
startActivity(intent);
Gaurav Vashisth
sumber
4
Ini tidak bekerja. Saya masih bisa pergi ke ProfileActivity menggunakan tombol kembali
Archie.bpgc
1

Tidak ada satu pun dari flag maksud yang berfungsi untuk saya, tetapi beginilah cara saya memperbaikinya:

Ketika pengguna keluar dari satu aktivitas, saya harus menyiarkan pesan dari aktivitas itu, lalu menerimanya dalam aktivitas yang ingin saya tutup, setelah itu saya sebut finish (); dan itu bekerja dengan cukup baik.

Ian Wambai
sumber
1

Coba ini akan berhasil:

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();
Mohammad
sumber
1

Di API level 11 atau lebih tinggi, gunakan FLAG_ACTIVITY_CLEAR_TASKdan FLAG_ACTIVITY_NEW_TASKtandai di Intent untuk menghapus semua tumpukan aktivitas.

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);
S. Sathya Priya
sumber
0

Gunakan ini

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();
Kumar Prashant
sumber
tahukah Anda setFlags dan addFlags?
GvSharma
0

tambahkan ke Manifest untuk aktivitas Anda android:launchMode="singleTask"

Hally Trần
sumber
0

Kotlin yang Canggih dan Dapat Digunakan Kembali:

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

intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK

Jika Anda berencana untuk menggunakannya secara teratur, buat fungsi ekstensi Intent

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

Anda kemudian bisa langsung memanggil fungsi ini sebelum memulai maksud

intent.clearStack()

Jika Anda memerlukan opsi untuk menambahkan tanda tambahan dalam situasi lain, tambahkan parameter 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