Android: ล้างสแต็คด้านหลัง


330

ใน Android ฉันมีกิจกรรมบางอย่างสมมติว่า A, B, C

ใน A ฉันใช้รหัสนี้เพื่อเปิด B:

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

ใน B ฉันใช้รหัสนี้เพื่อเปิด C:

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

เมื่อผู้ใช้แตะปุ่มใน C ฉันต้องการกลับไปที่ A และล้าง back stack (ปิดทั้ง B และ C) ดังนั้นเมื่อผู้ใช้ใช้ปุ่มย้อนกลับ B และ C จะไม่ปรากฏขึ้นฉันได้ลองทำสิ่งต่อไปนี้:

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

แต่ B และ C ยังคงปรากฏขึ้นหากฉันใช้ปุ่มย้อนกลับเมื่อฉันกลับไปทำกิจกรรม A. ฉันจะหลีกเลี่ยงสิ่งนี้ได้อย่างไร

คำตอบ:


438

ลองเพิ่มFLAG_ACTIVITY_NEW_TASKตามที่อธิบายไว้ในเอกสารสำหรับFLAG_ACTIVITY_CLEAR_TOP:

โหมดการเรียกใช้นี้ยังสามารถใช้เพื่อให้เกิดผลดีร่วมกับ FLAG_ACTIVITY_NEW_TASK: หากใช้เพื่อเริ่มกิจกรรมรูทของงาน สิ่งนี้มีประโยชน์เป็นพิเศษตัวอย่างเช่นเมื่อเริ่มต้นกิจกรรมจากตัวจัดการการแจ้งเตือน

ดังนั้นรหัสของคุณที่จะเปิดตัวAจะเป็น:

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.

28
ขอบคุณ แต่ฉันได้ลองแล้ว เมื่อฉันแตะปุ่มย้อนกลับหลังจากที่มันแสดง C อีกครั้ง ฉันจะพลาดอะไรได้บ้าง
Martin

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

8
ไม่ทำงานสำหรับฉัน แต่การโทรเสร็จสิ้น () ที่กิจกรรมแหล่งข้อมูลทำสิ่งที่ฉันต้องการเพื่อให้บรรลุ
2cupsOfTech

10
ฉันมีปัญหาเดียวกันกับที่มันไม่ทำงาน สิ่งที่แก้ไขได้สำหรับฉันคือโทรเสร็จสิ้น () หลังจากเริ่มกิจกรรมใหม่
Arno

20
ฉันยังเพิ่มเจตนาที่ชัดเจนอีกหนึ่งเจตนา = เจตนาใหม่ (SingUpActivity.this นี้, LoginActivity.class); เจตนา startActivity (เจตนา); เสร็จสิ้น();
Sam

147
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

8
ด้วยความเคารพต่อCLEAR_TOPธง - ชุดค่าผสมนี้เป็นชุดค่าผสมเดียวที่ล้างค่าสแต็กทั้งหมดและทำให้กิจกรรมใหม่เป็นกิจกรรมเดียวในแอป ขอบคุณ!
Aviel Gross

8
ข้อแตกต่างระหว่างสิ่งนี้กับคำตอบที่ยอมรับคืออะไร
Yuri Heupa

7
ขอบคุณความแตกต่างกับคำตอบที่ยอมรับคือด้วยธงนี้เราไม่จำเป็นต้องโทรหากิจกรรม
เสร็จสิ้น

1
FLAG_ACTIVITY_CLEAR_TASK ทำงานร่วมกันอย่างสมบูรณ์แบบกับ NEW_TASK
Shamsul Arefin Sajib

1
นี่ควรเป็นคำตอบที่ยอมรับได้ ขอบคุณมาก.
MD เดนมาร์ก Ansari

77

สิ่งที่เกี่ยวกับการเพิ่มไฟล์รายการสำหรับกิจกรรมที่เกี่ยวข้อง:

android:noHistory="true"

ถึงนิยามกิจกรรมของ B และ C? พวกเขาจะไม่ถูกเพิ่มใน backstack ไม่แน่ใจว่าเป็นสิ่งที่คุณต้องการหรือไม่


3
ระวังให้มากในขณะที่ใช้สิ่งนี้ - หากคุณใช้ล็อกอินด้วย FB หรือฟังก์ชันอื่น ๆ ที่คล้ายกัน
Skynet

2
@Skynet ทำไม ปัญหาที่เกี่ยวข้องกับการทำเช่นนี้คืออะไร?
Alfie Woodland

8
เมื่อคุณผ่านการควบคุมไปที่ FB เพื่อเข้าสู่ระบบจากหน้าเว็บที่ไม่มีประวัติจริงแอพ FB ไม่ได้อยู่ที่ใดหลังจากเข้าสู่ระบบของผู้ใช้ในกรณีของฉันมันกลับไปที่หน้าจอหลักของโทรศัพท์และฉันเกือบสูญเสียงานของฉัน!
Skynet

สิ่งนี้ไม่อนุญาตให้มีการเพิ่มกิจกรรมในแบ็คสแต็ค .... นี่ไม่ใช่วิธีแก้ไขที่ถูกต้อง
Tarun

ฉันกำลังมองหาอย่างแน่นอน
Masum

63

สิ่งนี้ทำให้ฉันรำคาญเป็นเวลานานในที่สุดฉันก็ทำมันออกมาโดยทำสิ่งนี้:

ในส่วนให้ใช้:

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

ในกิจกรรมให้ใช้ (เพิ่มการตั้งค่าสถานะความตั้งใจอีกหนึ่งรายการIntent.FLAG_ACTIVITY_CLEAR_TASKเปรียบเทียบกับส่วน)

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

1
หากคุณกำลังใช้งาน androidannotations คุณต้องเพิ่ม: Intent.FLAG_ACTIVITY_CLEAR_TASK
yosafatade

กิจกรรม solutioin ทำงานได้ดีสำหรับฉัน แม้ว่าฉันจะคิดด้วย API 16 การแก้ปัญหาจาก Daniel Schuler นั้นง่ายกว่า
PhilippS

ขอบคุณ yosafatade นั่นคือสิ่งที่ฉันขาดไป!
Marty Miller

30
  1. เพิ่มandroid:launchMode="singleTop"ไปยังองค์ประกอบกิจกรรมในรายการของคุณสำหรับกิจกรรม A
  2. จากนั้นใช้intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) และ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)เมื่อเริ่มต้นกิจกรรม A

ซึ่งหมายความว่าเมื่อเปิดใช้งานกิจกรรม A งานทั้งหมดที่อยู่ด้านบนจะถูกล้างออกเพื่อให้ A อยู่ด้านบน สแต็กหลังใหม่ถูกสร้างขึ้นด้วย A ที่รูทและการใช้singleTopทำให้คุณมั่นใจได้ว่าจะเปิด A ครั้งเดียวเท่านั้น (เนื่องจาก A อยู่ด้านบนเนื่องจาก..._CLEAR_TOP)


3
ใช่. นี่คือสิ่งที่ฉันใช้ตอนนี้ แต่มันไม่ได้ทำ Still C แสดงขึ้นเมื่อฉันกดปุ่มย้อนกลับ
Martin

แปลกฉันใช้มันในโครงการและใช้งานได้ดี ... การกดย้อนกลับพาฉันไปที่หน้าจอหลัก อาจมีสิ่งอื่นเกิดขึ้น คุณสามารถโพสต์รายการของคุณ?
โจเซฟเอิร์ล

ฉันรีสตาร์ทเครื่องจำลองและตอนนี้ดูเหมือนว่าจะทำงานได้เหมือนที่คุณพูด ขอบคุณมาก ๆ สำหรับความช่วยเหลือของคุณ!
Martin

singleTop ไม่ควรเกี่ยวข้องกับการเคลียร์สแต็ก
stdout

29

เริ่มต้นที่ API 16 (Jelly Bean) คุณสามารถโทรfinishAffinity()ได้

ตอนนี้คุณสามารถโทรActivityCompat.finishAffinity(Activity activity)ด้วยไลบรารีความเข้ากันได้

ตรวจสอบให้แน่ใจว่าตั้งค่า taskAffinity ในไฟล์ Manifest เป็นชื่อแพ็กเกจที่ไม่ซ้ำกับกลุ่มของกิจกรรมนั้น

ดูข้อมูลเพิ่มเติมได้ที่:
http://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#finishAffinity%28android.app.Activity%29


โปรดแก้ปัญหาที่ใช้งานง่ายอีกครั้งถ้าคุณได้รับการแจ้งเตือนบน API 16 ทำงานให้ฉัน!
PhilippS

3
เตือนความจำ: สิ่งนี้จะใช้ได้เฉพาะกับกิจกรรมที่ใช้ชื่องานเดียวกันชื่อเดียวกัน
Ryan

สิ่งนี้ใช้ได้ผลก็ต่อเมื่อคุณมีกิจกรรมเดียวในประวัติศาสตร์
arsent


11

หากแอปพลิเคชันของคุณมี sdk ขั้นต่ำเวอร์ชัน 16 คุณสามารถใช้ finishAffinity ()

เสร็จสิ้นกิจกรรมนี้รวมถึงกิจกรรมทั้งหมดที่อยู่ด้านล่างในภารกิจปัจจุบันที่มีความสัมพันธ์แบบเดียวกัน

หน้าจอนี้ใช้งานได้สำหรับฉันในการชำระเงินสูงสุดลบการเปิดใช้งานการย้อนกลับทั้งหมด

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

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



8

สำหรับการวิจัยในอนาคตลองใช้รหัสนี้

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

ในที่สุดธงเหล่านี้ก็ได้ผลสำหรับฉัน สิ่งที่ฉันทำคือฉันเริ่มกิจกรรมเดียวกับที่ฉันอยู่กับธงเหล่านี้และ EXIT บูลีน = จริง ใน onCreate () ฉันตรวจสอบพารามิเตอร์การเรียกใช้สำหรับ EXIT และเรียกว่า finish () หากตั้งค่าเป็นจริง มันเป็นเรื่องยุ่งยากมากที่จะปิดแอปของคุณเอง
Janne Oksanen

8

ใช้ finishAffinity (); ในภารกิจ C เมื่อเริ่มงาน A เพื่อล้างกิจกรรมแบ็คสแต็ค


คำตอบนี้ใช้ได้สำหรับฉันเท่านั้น เจตนาไม่ต้องการ FLAG_ACTIVITY_CLEAR_TOP และเจตนา FLAG_ACTIVITY_NEW_TASK
nuttynibbles

7

ใช้รหัสนี้เพื่อเริ่มกิจกรรมใหม่และปิดหรือทำลายสแต็กกิจกรรมอื่น ๆ ทั้งหมดหรือสแต็กย้อนกลับ

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

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.

5

ฉันพบวิธีแก้ปัญหาที่น่าสนใจซึ่งอาจช่วยได้ ฉันทำสิ่งนี้ในonBackPressed()วิธีการของฉัน

finishAffinity();
finish();

FinishAffinityลบการเชื่อมต่อของกิจกรรมที่มีอยู่ไปยังสแต็กของมัน จากนั้นเสร็จสิ้นจะช่วยให้คุณออกจากกิจกรรมนั้น ซึ่งในที่สุดจะออกจากแอปพลิเคชัน


4

ฉันพบคำตอบที่ทำให้เข้าใจผิดเล็กน้อยที่นี่เพราะรหัสในคำถามเดิมดูเหมือนว่าจะทำงานได้ดีสำหรับฉัน

ด้วย A เป็นกิจกรรมรูทการเริ่มต้นจาก B หรือ C เท่านั้นด้วย FLAG_ACTIVITY_CLEAR_TOP จะลบ B และ C ออกจากสแต็กหลัง


4

ใน kotlin มันเกือบจะเหมือนกับ java เท่านั้น| สัญลักษณ์ถูกแทนที่ด้วยหรือข้อความ ดังนั้นมันเขียนเหมือน -

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)

3

ฉันลองวิธีแก้ปัญหาทั้งหมดและไม่มีใครทำงานเป็นรายบุคคลสำหรับฉัน โซลูชันของฉันคือ:

ประกาศActivity Aเป็นSingleTopโดยใช้[android:launchMode="singleTop"]ใน Android อย่างชัดแจ้ง

ตอนนี้เพิ่มการตั้งค่าสถานะต่อไปนี้ในขณะที่เปิดAจากที่ใดก็ได้ มันจะล้างสแต็ค

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

2

Intent.FLAG_ACTIVITY_CLEAR_TOPจะไม่ทำงานในกรณีนี้ โปรดใช้(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK)

สำหรับรายละเอียดเพิ่มเติมโปรดตรวจสอบนี้เอกสาร


2

มันเสียงที่ฉันชอบคุณจะต้องเริ่มต้นActivity Cจากการโดยใช้Activity B startActivityForResult()เมื่อคุณคลิกปุ่มการActivity CโทรsetResult(RESULT_OK)และfinish()อื่น ๆActivity Cจะสิ้นสุดลง ในActivity BคุณสามารถมีonActivityResult()การตอบสนองโดยยังเรียกร้องกับตัวเองและคุณแล้วจะถูกนำกลับไปfinish()Activity A


7
ใช่ แต่ถ้ามี 42 กิจกรรมระหว่าง A และ C นี่จะค่อนข้างน่าเบื่อ การตั้งค่าสถานะ FLAG_ACTIVITY_CLEAR_TOP ควรทำในสิ่งที่ OP ต้องการโดยตรง
Guillaume Brunerie

นี่จะเป็นวิธีที่ดีที่สุดในการบรรลุสิ่งที่ OP ต้องการและตามที่ @Guillaume กล่าวว่าจะต้องใช้รหัสในกิจกรรมทั้งหมดระหว่างรูทและด้านบนสุดของสแต็ก
Jake Basile

บันทึกรับรองสำเนาถูกต้อง. นี่คือธงที่ฉันต้องเรียนรู้อย่างชัดเจน
Maximus


1

คุณสามารถใช้ตัวอย่างนี้เพื่อโทรActivity AจากActivity C

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


1

สำหรับฉันเพิ่มIntent.FLAG_ACTIVITY_CLEAR_TASKแก้ปัญหาได้

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

1

ขั้นสูงนำมาใช้ซ้ำ Kotlin:

คุณสามารถตั้งค่าสถานะโดยตรงโดยใช้วิธีการตั้งค่า ใน Kotlin orเป็นทดแทนสำหรับบิต Java |หรือ

intent.flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK

หากใช้สิ่งนี้มากกว่าหนึ่งครั้งให้สร้างฟังก์ชันส่วนขยายเจตนา

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

จากนั้นคุณสามารถเรียกใช้ฟังก์ชันนี้โดยตรงก่อนที่จะเริ่มเจตนา

intent.clearStack()

หากคุณต้องการตัวเลือกในการเพิ่มการตั้งค่าสถานะเพิ่มเติมในสถานการณ์อื่น ๆ ให้เพิ่มพารามิเตอร์เสริมลงในฟังก์ชันส่วนขยาย

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

0

นอกจากนี้FLAG_ACTIVITY_CLEAR_TOPคุณอาจลองเพิ่มIntent.FLAG_ACTIVITY_SINGLE_TOPด้วย:

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


นั่นจะส่งผลต่อกิจกรรมที่ด้านบนสุดของสแต็กไม่ใช่รากของมัน
Jake Basile

0

รหัสที่กำหนดทำงานได้อย่างถูกต้อง ฉันลองในตัวอย่าง Application Life Cycle แล้ว

ฉันไม่ได้รับ B และ C ในแบ็คสแต็คหลังจากเริ่มกิจกรรม A ด้วยค่าสถานะ FLAG_ACTIVITY_CLEAR_TOP


0

ฉันโทรไปactivity_name.this.finish()หลังจากเริ่มเจตนาใหม่และมันก็ใช้ได้ผลสำหรับฉัน

I tried "FLAG_ACTIVITY_CLEAR_TOP" and "FLAG_ACTIVITY_NEW_TASK"

แต่มันจะไม่ทำงานสำหรับฉัน ... ฉันไม่ได้แนะนำวิธีแก้ปัญหานี้ให้ใช้ แต่ถ้าการตั้งค่าสถานะไม่ทำงานสำหรับคุณมากกว่าที่คุณสามารถลอง .. แต่ยังฉันขอแนะนำอย่าใช้มัน


0

เพิ่ม NO History Flag ในเจตนา

ในกิจกรรม B ให้เริ่มกิจกรรม C ดังต่อไปนี้ >>>>>>

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


0

เพิ่มสิ่งนี้ในของคุณActivity BและActivity C

android:noHistory="true"

หรือฟังก์ชั่นเพื่อหลีกเลี่ยงการกลับกดด้วยOverride onBackPressedreturn

@Override
public void onBackPressed() {
   return;
}

0

ใช้เมธอด setFlags () เพื่อเปิดด้านหลังที่ชัดเจนเปิดกิจกรรมทั้งหมดและเริ่มyourActvity

Intent intent = new Intent(getApplicationContext(), yourActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.