Selesaikan semua aktivitas sebelumnya

368

Aplikasi saya memiliki layar alur berikut:

Home->screen 1->screen 2->screen 3->screen 4->screen 5

Sekarang saya memiliki log out tombol umum di setiap layar

( Home/ screen 1 / screen 2 /screen 3/ screen 4 / screen 5)

Saya ingin bahwa ketika pengguna mengklik tombol logout (dari layar apa saja), semua layar akan selesai dan layar baru Log in akan terbuka.

Saya telah mencoba hampir semua FLAG_ACTIVITYuntuk mencapai ini. Saya juga melewati beberapa jawaban di stackoverflow, tetapi tidak bisa menyelesaikan masalah. Aplikasi saya ada di Android 1.6 jadi tidak bisa digunakanFLAG_ACTIVITY_CLEAR_TASK

Apakah ada cara untuk menyelesaikan masalah ini?

Tanmay Mandal
sumber
Apakah Anda menjalankan aktivitas bersarang menggunakan startActivityForResult?
woodshy
tidak. Semua kegiatan dimulai dengan startActivity.
Tanmay Mandal
Saya menggunakan aktivitas bersarang sementara cod menjalankan finishaffinitytask () dalam aktivitas bersarang. apakah itu mengubah perilaku? karena kadang-kadang saya mendapatkan Kegagalan memberikan ResultInfo hasil ketika finishaffinitytask berjalan.
Ripal Tamboli
Silakan periksa jawaban ini, Ini pasti akan membantu Anda stackoverflow.com/a/25159180/2732632
Kimmi Dhingra
3
Android 21 memperkenalkan Activity.finishAndRemoveTask ().
Joseph Johnson

Jawaban:

543

Menggunakan:

Intent intent = new Intent(getApplicationContext(), Home.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Ini akan menghapus semua kegiatan di atas rumah.

Dengan asumsi Anda menyelesaikan layar login ketika pengguna login dan home dibuat dan setelah itu semua layar dari 1 hingga 5 di atas yang itu. Kode yang saya poskan akan mengembalikan Anda ke layar beranda menyelesaikan semua aktivitas lainnya. Anda dapat menambahkan ekstra di maksud dan membacanya di aktivitas layar beranda dan menyelesaikannya juga (mungkin meluncurkan layar login lagi dari sana atau sesuatu).

Saya tidak yakin tetapi Anda juga dapat mencoba masuk dengan bendera ini. Saya tidak tahu bagaimana kegiatan akan dipesan dalam kasus itu. Jadi tidak tahu apakah itu akan menghapus yang ada di bawah layar yang Anda aktifkan termasuk yang sedang Anda gunakan tetapi pasti cara yang harus dilakukan.

Semoga ini membantu.

DArkO
sumber
Pengguna menampilkan layar pertamanya sebagai layar beranda, itulah masalah utamanya.
Tanmay Mandal
dan saya punya tanggapan saya Anda harus kembali ke layar awal dan menyelesaikan yang itu. jadi proses memanggil maksud di atas dari layar apa pun. menerima maksud di layar Utama dan langsung meluncurkan niat ke arah masuk dan menyelesaikan rumah setelah metode startActivity. Anda juga dapat mengganti animasi yang tertunda menjadi nol untuk masuk dan keluar sehingga tidak menunjukkan transisi (saya melakukan itu karena rasanya agak lebih cepat).
DArkO
10
Daripada mendeklarasikan aktivitas sebagai singleInstance, pertimbangkan menggunakan FLAG_ACTIVITY_CLEAR_TOP|FLAG_ACTIVITY_SINGLE_TOPsebagai bendera untuk Intent. Ini akan menyelesaikan aktivitas intervensi dan memulai (atau membawa kembali ke latar depan) aktivitas yang diinginkan.
CommonsWare
13
@ CommonsWare Menambah intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);aktivitas saya tidak membantu saya. Itu tidak menyelesaikan kegiatan intervensi. Ketika saya menekan kembali dari layar Login saya bisa melihat kegiatan sebelumnya. Berikut adalah kode saya Intent intent=new Intent(BaseActivity.this, Login.class);intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);startActivity(intent);.
Tanmay Mandal
26
kode ini hanya menghapus tumpukan aktivitas teratas, untuk menghapus semua intent.addFlags aktivitas (Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
Ajay Venugopal
318

Anda boleh mencoba Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK. Ini akan benar-benar menghapus semua aktivitas sebelumnya dan memulai aktivitas baru.

Kong Ken
sumber
11
Solusi yang tepat, tetapi hanya API 11+
riwnodennyk
Saya akhirnya menggunakan flag tambahan ini karena tidak menyebabkan penundaan saat menampilkan aktivitas utama (itu tidak akan memulai kembali jadi itu jauh lebih cepat).
Maurizio
2
@riwnodennyk mengapa API 11+?
Muhammad Babar
17
Gunakan IntentCompat.FLAG_ACTIVITY_CLEAR_TASK untuk versi pra 11
Steven Pena
2
@ono Ya. Hanya itu yang Anda butuhkan. Pastikan mode peluncuran aktivitas target Anda ditetapkan sebagai "singleTask" di manifes.
Steven Pena
137

Sebelum meluncurkan Aktivitas baru Anda, cukup tambahkan kode berikut:

finishAffinity();

Atau jika Anda ingin berfungsi di Android versi sebelumnya:

ActivityCompat.finishAffinity(this);
Henrique
sumber
12
ActivityCompat.finishAffinity (ini); panggilan activity.finish () untuk api <16. Jadi itu tidak akan berhasil.
Aamir Abro
1
@Beto Caldas, saya sendiri sudah mengkonfirmasi kode sumbernya, itu tidak akan berfungsi untuk API <16 seperti yang disebutkan AamirAbro. Itu hanya akan menyelesaikan aktivitas yang Anda
berikan
39

Ketika pengguna ingin keluar dari semua aktivitas terbuka , mereka harus menekan tombol yang memuat Aktivitas pertama yang berjalan saat aplikasi Anda mulai, menghapus semua aktivitas lain, lalu menyelesaikan sisa aktivitas yang terakhir. Biarkan kode berikut dijalankan ketika pengguna menekan tombol keluar. Dalam kasus saya, LoginActivityadalah aktivitas pertama dalam program saya untuk dijalankan.

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("EXIT", true);
startActivity(intent);

Kode di atas menghapus semua aktivitas kecuali untuk LoginActivity. Kemudian masukkan kode berikut ke dalam LoginActivity's onCreate(...), untuk mendengarkan kapan LoginActivitydiciptakan kembali dan sinyal' EXIT 'berlalu:

if (getIntent().getBooleanExtra("EXIT", false)) {
    finish();  
}

Mengapa membuat tombol keluar di Android begitu sulit?

Android berusaha keras untuk mencegah Anda memiliki tombol "keluar" di aplikasi Anda, karena mereka ingin pengguna tidak pernah peduli apakah program yang mereka gunakan berjalan di latar belakang atau tidak.

Pengembang OS Android ingin agar program Anda dapat bertahan dari pematian yang tidak terduga dan matikan telepon, dan ketika pengguna memulai kembali program, mereka mengambil tepat di mana mereka tinggalkan. Jadi pengguna dapat menerima panggilan telepon saat mereka menggunakan aplikasi Anda, dan membuka peta yang mengharuskan aplikasi Anda dibebaskan untuk sumber daya yang lebih banyak.

Ketika pengguna melanjutkan aplikasi Anda, mereka mengambil tepat di mana mereka tinggalkan tanpa gangguan. Tombol keluar ini mengambil daya dari pengelola aktivitas, yang berpotensi menyebabkan masalah dengan siklus hidup program android yang dikelola secara otomatis.

Eric Leschinski
sumber
31
Intent intent = new Intent(this, classObject);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

Ini akan bekerja untuk semua versi Android. Di mana IntentCompatkelas ditambahkan di pustaka Dukungan Android.

Permata
sumber
IntentCompat.FLAG_ACTIVITY_CLEAR_TASKtidak dikenali, gunakan Intentsebagai ganti IntentCompat.
CoolMind
30

Gunakan yang berikut untuk aktivitas

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

hapus bendera CLEAR_TASK untuk penggunaan fragmen.

Saya harap ini dapat digunakan untuk beberapa orang.

Aristo Michael
sumber
24

Saya kira saya terlambat tetapi ada jawaban yang sederhana dan singkat. Ada metode finishAffinity () di Aktivitas yang akan menyelesaikan aktivitas saat ini dan semua aktivitas induk, tetapi hanya berfungsi di Android 4.1 atau lebih tinggi.

Untuk API 16+, gunakan

finishAffinity();

Untuk di bawah 16, gunakan

ActivityCompat.finishAffinity(YourActivity.this);

Semoga ini bisa membantu!

Akshay Taru
sumber
21

Dari developer.android.com :

public void finishAffinity ()

Ditambahkan dalam API level 16

Selesaikan aktivitas ini dan juga semua aktivitas tepat di bawahnya dalam tugas saat ini yang memiliki afinitas yang sama. Ini biasanya digunakan ketika aplikasi dapat diluncurkan ke tugas lain (seperti dari ACTION_VIEW jenis konten yang dimengerti) dan pengguna telah menggunakan navigasi atas untuk beralih dari tugas saat ini dan ke tugasnya sendiri. Dalam hal ini, jika pengguna telah menavigasi ke aktivitas lain dari aplikasi kedua, semua itu harus dihapus dari tugas asli sebagai bagian dari pengalih tugas.

Perhatikan bahwa penyelesaian ini tidak memungkinkan Anda untuk memberikan hasil ke aktivitas sebelumnya, dan pengecualian akan dilemparkan jika Anda mencoba melakukannya.

gmrl
sumber
19

Di samping catatan, baik untuk mengetahui
Jawaban ini berfungsi ( https://stackoverflow.com/a/13468685/7034327 )

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

padahal ini tidak berhasil

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

.setFlags() mengganti semua flag sebelumnya dan tidak menambahkan flag baru apa .addFlags()pun.

Jadi ini juga akan berhasil

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
John
sumber
Penjelasan hebat tentang perbedaan antara setFlag vs addFlag, terima kasih
Pelanes
13

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
10

Solusi yang saya terapkan untuk ini (saya pikir saya menemukannya di Stack Overflow di suatu tempat, tapi saya tidak ingat, jadi terima kasih kepada siapa pun yang melakukan itu di tempat pertama):

Dari aktivitas Anda lakukan ini:

// Clear your session, remove preferences, etc.
Intent intent  = new Intent(getBaseContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

Kemudian di LoginActivity Anda, timpa onKeyDown:

public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        moveTaskToBack(true);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}
Andy
sumber
3
Itu biasanya ide yang sangat buruk, itu mungkin berhasil, itu memperkenalkan titik kontak yang mungkin rusak di masa depan dan akan sulit untuk debug. Saya katakan dari pengalaman :)
Martin Marconcini
10

Untuk tombol logout di layar terakhir aplikasi, gunakan kode ini pada pendengar tombol logout untuk menyelesaikan semua aktivitas terbuka sebelumnya, dan masalah Anda terpecahkan.

{
Intent intent = new Intent(this, loginScreen.class);
ntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
Amrit
sumber
8
    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();
Prashant Kumar
sumber
6
mengapa FLAG_ACTIVITY_CLEAR_TASK dua kali?
Choletski
1
Dari apa yang saya mengerti, .setFlags menggantikan flag sebelumnya dan tidak menambahkan flag apa pun. .addFlags adalah apa yang ingin Anda gunakan, saya kira? Penyebab semua kode di atas i1.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); terhapus
iOSAndroidWindowsMobileAppsDev
addFlags Bekerja untuk saya
Jamil
1
setFlagsakan mengganti semua sebelumnya, jadi yang terakhir setFlagshanya valid, yang sebelumnya diganti. Jadi, Anda tidak perlu meneleponi1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); i1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
mtrakal
8

saya memiliki masalah yang sama yang dapat Anda gunakan IntentCompat, seperti ini:

import android.support.v4.content.IntentCompat;
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);

kode ini berfungsi untuk saya.

Android api 17

Adnan Abdollah Zaki
sumber
8

Dalam kasus saya, saya menggunakan finishAffinity()fungsi dalam aktivitas terakhir seperti:

finishAffinity()
startHomeActivity()

Semoga bermanfaat.

Djek-Grif
sumber
7

alih-alih menggunakan finish()gunakan sajafinishAffinity();

Hitesh Kushwah
sumber
1
Jawaban yang bagus tetapi membutuhkan API 16
Akshay Taru
6

Masuk -> Home-> layar 1-> layar 2-> layar 3-> layar 4-> layar 5

di layar 4 (atau yang lain) ->

StartActivity (Masuk)
dengan
FLAG_ACTIVITY_CLEAR_TOP

Plamen Nikolov
sumber
2
Ketika saya menekan tombol kembali semua aktivitas sebelumnya ditampilkan dalam urutan mereka. Kegiatan itu harus ditutup, ketika tombol logout diklik hanya akan ada satu aktivitas di tumpukan dan itu akan menjadi aktivitas login. Dan tidak ada aktivitas login. layar masuk. Pengguna mulai dari layar beranda.
Tanmay Mandal
6

untuk API> = 15 hingga API 23 solusi sederhana.

 Intent nextScreen = new Intent(currentActivity.this, MainActivity.class);
 nextScreen.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
 startActivity(nextScreen);
 ActivityCompat.finishAffinity(currentActivity.this);
Kamal Bunkar
sumber
Rumuskan jawaban Anda sehingga semua orang bisa mendapat manfaat darinya.
Shubhamoy
5

Jika Anda menggunakan startActivityForResult()dalam aktivitas Anda sebelumnya, cukup timpa OnActivityResult()dan panggil finish();metode di dalamnya dalam semua aktivitas .. Ini akan melakukan pekerjaan ...

ngesh
sumber
Tidak, saya startActivityhanya menggunakan .
Tanmay Mandal
Akan sulit untuk mempertahankan onActivityResultsetiap kegiatan. Saya telah menerapkan saran DArkO dan mencapai tujuan saya dan terima kasih atas bantuannya.
Tanmay Mandal
3

Ketika pengguna mengklik tombol logout lalu tulis kode berikut:

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

Dan juga ketika setelah login jika Anda menelepon aktivitas baru jangan gunakan finish ();

nikki
sumber
2

Cukup, ketika Anda pergi dari layar login, bukan saat menyelesaikan layar login.

Dan kemudian dalam semua aktivitas maju, gunakan ini untuk logout:

final Intent intent = new Intent(getBaseContext(), LoginScreen.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);

Ini bekerja dengan sempurna.

Asad Rao
sumber
1

Jika Anda masuk pengguna screen 1dan dari sana Anda pergi ke layar lain, gunakan

Intent intent = new Intent(this, Screen1.class);
intent.addFlags(FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
Gabriel Negut
sumber
Ketika saya menekan tombol kembali semua aktivitas sebelumnya ditampilkan dalam urutannya. Aktivitas itu harus ditutup, ketika tombol logout diklik hanya akan ada satu aktivitas di stack dan itu akan menjadi aktivitas login.
Tanmay Mandal
Jika Anda menginginkan perilaku ini, Anda harus mengganti onKeyDowndan onBackPressed(atau onKeyDown, jika Anda ingin mendukung versi Android <2.0) di masing-masing kegiatan Anda (kecuali yang masuk), dan di startActivity(login)sana seperti yang ditunjukkan di atas.
Gabriel Negut
Saya memiliki tombol yang akan membawa saya ke layar masuk menyelesaikan semua kegiatan di stack. Apakah mungkin?
Tanmay Mandal
1

Saya menemukan cara ini, itu akan menghapus semua riwayat dan keluar

Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
Intent intent = new Intent(getApplicationContext(), SplashScreen.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

finish();
System.exit(0);
pirooz jenabi
sumber
1

Saya kira saya terlambat tetapi ada jawaban yang sederhana dan singkat. Ada metode finishAffinity () di Aktivitas yang akan menyelesaikan aktivitas saat ini dan semua aktivitas induk, tetapi hanya berfungsi di Android 4.1 atau lebih tinggi.

Untuk API 16+, gunakan

finishAffinity ();

Untuk di bawah 16, gunakan

ActivityCompat.finishAffinity (YourActivity.this);

Semoga ini bisa membantu!

shareedit menjawab 27 Mei 18 pada 8:03

Akshay Taru

Samuel Quiroz
sumber
0

Saya menemukan solusi ini berfungsi di setiap perangkat meskipun tingkat API (bahkan untuk <11)

Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
ComponentName cn = intent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(cn);
startActivity(mainIntent);
priyankvex
sumber
0

Cara terbaik untuk menutup semua aktivitas sebelumnya dan menghapus memori

finishAffinity()
System.exit(0);
Shivam Tripathi
sumber
0
startActivity(
                Intent(this, LoginActivity::class.java)
                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    .addFlags(FLAG_ACTIVITY_CLEAR_TASK)
            )
Kishan Solanki
sumber