Menghapus suatu aktivitas dari tumpukan riwayat


382

Aplikasi saya menunjukkan aktivitas pendaftaran saat pertama kali pengguna menjalankan aplikasi, terlihat seperti:

  1. ActivitySplashScreen (selamat datang di game, daftar untuk akun?)
  2. ActivitySplashScreenSignUp (hebat, isi info ini)
  3. ActivityGameMain (layar game utama)

sehingga aktivitas saling meluncurkan dengan urutan yang tepat, ketika pengguna mengklik tombol di setiap layar.

Ketika pengguna beralih dari aktivitas # 2 ke # 3, apakah mungkin untuk menghapus # 1 dan # 2 dari tumpukan sejarah sepenuhnya? Saya suka sehingga jika pengguna berada di # 3, dan menekan tombol kembali, mereka hanya pergi ke homescreen, alih-alih kembali ke layar splash.

Saya pikir saya bisa menyelesaikan ini dengan tugas-tugas (mis. Memulai tugas baru di # 3) tetapi ingin melihat apakah ada metode yang lebih sederhana,

Terima kasih


Setelah berada di layar beranda, saat pengguna melanjutkan aplikasi Anda, apakah ia membawanya ke ActivitySplashScreen atau ActivityGameMain?
Tamil

Jawaban:


632

Anda dapat mencapai ini dengan mengatur android:noHistory atribut ke "true"dalam <activity>entri yang relevan di AndroidManifest.xmlfile Anda . Sebagai contoh:

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

12
Ini adalah cara terbaik untuk melakukannya.
shkschneider

22
Setara Anda bisa menggunakan FLAG_ACTIVITY_NO_HISTORY.
Timmmm

34
Bagaimana saya bisa mencapai ini dari kode? Karena saya tidak ingin melakukan ini sepanjang waktu. Saya ingin menghapus aktivitas yang diberikan dari riwayat hanya dalam beberapa kondisi.
Namratha

8
Perlu diketahui bahwa menggunakan atribut noHistory akan membuat aktivitas tersebut selesai, yang dapat menyebabkan perilaku tak terduga dengan login G + misalnya. Lihat: stackoverflow.com/questions/20383878/… Butuh beberapa saat untuk menemukan bug ini karena aplikasi saya terus mogok tanpa jejak.
Acapulco

13
Sulit untuk menyalin bendera yang diperlukan karena itu adalah tautan, jadi di sini salah satu yang dapat dengan mudah disalin. android:noHistory="true"
MirroredFate

137

Anda dapat menggunakan penerusan untuk menghapus aktivitas sebelumnya dari tumpukan aktivitas sambil meluncurkan yang berikutnya. Ada contohnya di APIDEMOS , tetapi pada dasarnya semua yang Anda lakukan adalah menelepon finish()segera setelah menelepon startActivity().


1
Hai Daniel, saya membaca contohnya, tetapi itu hanya akan menghapus setumpuk riwayat dengan 1 aktivitas, bukan? Jika tumpukan saya terlihat seperti A, B, dan saya meluncurkan C, saya ingin C menjadi root baru dan menghapus A dan B. Dalam contoh SDK, memanggil finish () dari B akan membuat saya dengan setumpuk A , C, bukan? Terima kasih.
Mark

1
Anda dapat menghapus A saat meluncurkan B, dan menghapus B saat meluncurkan C; Namun, saya kira Anda tidak akan dapat mundur dari B ke A jika itu yang Anda inginkan. Saya harus memikirkan ini lagi jika itu masalah.
Dan Lew

3
Tandai, untuk mencapai apa yang Anda inginkan, Anda harus menggunakan bendera: FLAG_ACTIVITY_CLEAR_TOP. Saya harap ini membantu.
Francisco Junior

3
FLAG_ACTIVITY_CLEAR_TOPtidak akan berfungsi karena C belum ada di tumpukan belakang.
Timmmm

1
@DanielLew Ada banyak contoh dalam APIDEMOS. Anda memiliki nama contoh yang disarankan?
Stephane

52

46
Perhatikan bahwa ini tidak menetapkan riwayat untuk aktivitas yang Anda luncurkan. Agar tidak ada riwayat untuk aktivitas yang Anda luncurkan, saya hanya mengaturnya android:noHistory="true"di manifes.
georgiecasey

1
Ini bekerja dengan baik. Gunakan intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)untuk mengatur bendera ini.
vovahost

1
@georgiecasey ini berguna ketika kadang-kadang Anda ingin menyimpannya dalam sejarah dan kadang-kadang Anda tidak menginginkannya dalam sejarah.
Vihaan Verma

24

Ini mungkin bukan cara yang ideal untuk melakukannya. Jika seseorang memiliki cara yang lebih baik, saya akan menantikan untuk menerapkannya. Inilah cara saya menyelesaikan tugas khusus ini dengan pra-versi-11 SDK.

di setiap kelas Anda ingin pergi ketika waktu yang cerah, Anda perlu melakukan ini:

    ... 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();
    }
}

maka yang perlu mematikan rantai muncul dari tumpukan perlu hanya memanggil ini ketika Anda ingin memulainya:

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

Maka kegiatan tidak di tumpukan!
Ingat orang-orang, bahwa Anda dapat memulai suatu kegiatan, dan kemudian mulai membersihkan di belakangnya, eksekusi tidak mengikuti satu utas (ui).


Jika ada yang menemukan ini nanti, saya pikir itu mungkin terbukti penting untuk diketahui, jika Anda telah memutar layar, android akan sangat membantu me-restart aplikasi Anda ketika Anda menghapus aktivitas terakhir dari stack. Sadarilah ini!
Travis

Ini adalah jawaban yang bagus jika Anda hanya ingin menghapus suatu aktivitas dari tumpukan dengan syarat tergantung pada apa yang dilakukan pengguna dalam aktivitas selanjutnya +1
theMothaShip

23

Salah satu cara yang berfungsi sebelum API 11 adalah memulai ActivityGameMainterlebih dahulu, lalu di onCreateAktivitas tersebut mulailah ActivitySplashScreenaktivitas Anda . Tidak ActivityGameMainakan muncul saat Anda memanggil startActivity terlalu awal untuk splash.

Kemudian Anda dapat menghapus tumpukan ketika memulai ActivityGameMaindengan mengatur bendera ini pada Intent:

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

Anda juga harus menambahkan ini ke ActivitySplashScreen:

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

Sehingga menekan kembali aktivitas itu tidak kembali ke Anda ActivityGameMain.

Saya berasumsi bahwa Anda tidak ingin layar splash kembali ke baik, untuk mencapai ini saya sarankan mengaturnya noHistorydi Anda AndroidManifest.xml. Kemudian masukkan goBackPressedkode di ActivitySplashScreenSignUpkelas Anda sebagai gantinya.

Namun saya telah menemukan beberapa cara untuk memecahkan ini. Mulai aplikasi lain dari pemberitahuan saat ActivitySplashScreenSignUpditampilkan dan riwayat belakang tidak diatur ulang.

Satu-satunya cara nyata untuk mengatasi hal ini adalah di API 11:

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);

20

Saya menggunakan cara ini.

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

Terima kasih. Saya menemukan ini membantu jika ada tombol Home di menu saya, dan saya tidak ingin aktivitas yang ditumpuk muncul setelah pengguna mengklik rumah dari sana.
ghitesh

8

Saya tahu saya terlambat dalam hal ini (sudah dua tahun sejak pertanyaan diajukan) tetapi saya menyelesaikan ini dengan mencegat tombol kembali. Daripada memeriksa kegiatan tertentu, saya hanya melihat hitungan dan jika kurang dari 3 itu hanya mengirim aplikasi ke belakang (menjeda aplikasi dan mengembalikan pengguna ke apa pun yang sedang berjalan sebelum diluncurkan). Saya memeriksa kurang dari tiga karena saya hanya memiliki satu layar intro. Juga, saya memeriksa hitungan karena aplikasi saya memungkinkan pengguna untuk menavigasi kembali ke layar beranda melalui menu, jadi ini memungkinkan mereka untuk mencadangkan melalui layar lain seperti biasa jika ada kegiatan selain layar intro pada tumpukan.

//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

Dalam manifes Anda dapat menambahkan:

android:noHistory="true"

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

Anda juga bisa menelepon

finish()

segera setelah menelepon startActivity (..)


2
Lebih baik menggunakan flag aktivitas daripada menaruh sesuatu di manifes.
Trevor Hart


4

Sangat gila bahwa tidak ada yang menyebutkan solusi elegan ini. Ini harus menjadi jawaban yang diterima.

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

Kuncinya di sini adalah untuk digunakan intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); untuk perantara Activity. Setelah tautan tengah rusak, DashActivitykemauan yang pertama dan terakhir di tumpukan.

android:noHistory="true"adalah solusi yang buruk, karena menyebabkan masalah ketika mengandalkan Activitymisalnya sebagai callback onActivityResult. Ini adalah solusi yang direkomendasikan dan harus diterima.


1
Bendera itu kedengarannya terlalu bagus untuk menjadi kenyataan. FLAG_ACTIVITY_NO_HISTORY berfungsi dengan baik dan seperti yang diharapkan orang hingga menempatkan aplikasi ke latar belakang lalu latar depan lagi sambil memiliki aktivitas dengan bendera di atas tumpukan. Saat pergi ke latar belakang, aktivitasnya hancur. Ketika kembali ke aplikasi, orang akan melihat aktivitas sebelumnya dari tumpukan. Saya jelas tidak menginginkan perilaku seperti itu.
NeverwinterMoon

4

Sudah terlambat tetapi harap ini membantu. Sebagian besar jawaban tidak menunjuk ke arah yang benar. Ada dua bendera sederhana untuk itu.

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

Dari Android docs:

FLAG_ACTIVITY_CLEAR_TASK public int static final Ditambahkan di API level 11

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

aktivitas yang akan dihapus sebelum aktivitas dimulai. Yaitu, aktivitas menjadi akar baru dari tugas yang kosong, dan semua aktivitas lama selesai. Ini hanya dapat digunakan bersama dengan FLAG_ACTIVITY_NEW_TASK.


1

Panggil saja ini. Finish () sebelum startActivity (maksud) seperti ini-

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

pengguna yang memiliki kesalahan pada "ini", harus mengubahnya ke "ActivityOne.this"
ninbit

1

Menghapus aktivitas dari Riwayat dilakukan Dengan mengatur bendera sebelum aktivitas yang Tidak Anda inginkan

A-> B-> C-> D

Misalkan A, B, C dan D adalah 4 Kegiatan jika Anda ingin menghapus B dan C kemudian mengatur bendera

intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

Dalam kegiatan A dan B

Ini adalah sedikit kode

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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.