จบกิจกรรมจากกิจกรรมอื่น


101

ฉันต้องการจบกิจกรรมหนึ่งจากกิจกรรมอื่นเช่น:

ในกิจกรรม [A] เมื่อคลิกปุ่มฉันกำลังเรียกใช้กิจกรรม [B] โดยไม่ต้องจบกิจกรรม [A]

ตอนนี้ในกิจกรรม [b] มีสองปุ่มใหม่และปรับเปลี่ยน เมื่อผู้ใช้คลิกที่แก้ไขแล้วป๊อปกิจกรรม [A] จากสแต็กโดยมีตัวเลือกทั้งหมดถูกเลือก ..

แต่เมื่อผู้ใช้คลิกที่ปุ่มใหม่จากกิจกรรม [B] ฉันจะต้องจบกิจกรรม [A] จากกองซ้อนและโหลดกิจกรรมนั้น [A] อีกครั้งในสแต็ก

ฉันกำลังพยายามอยู่ แต่ฉันไม่สามารถจบกิจกรรม [A] จากสแต็กได้ ... ฉันจะทำได้อย่างไร?

ฉันใช้รหัสเป็น:

จากกิจกรรม [A]:

Intent GotoB = new Intent(A.this,B.class);
startActivityForResult(GotoB,1);

อีกวิธีหนึ่งในกิจกรรมเดียวกัน

public void onActivityResult(int requestCode, int resultCode, Intent intent) {

    if (requestCode == 1)
    {
        if (resultCode == 1) {
            Intent i = getIntent();
            overridePendingTransition(0, 0);
            i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
            finish();

            overridePendingTransition(0, 0);
            startActivity(i);
        }
    }
}

และในกิจกรรม [B] เมื่อคลิกปุ่ม:

setResult(1);
finish();

เฮ้คุณต้องการจบกิจกรรมหนึ่งจากอีกกิจกรรมหนึ่ง ... จากนั้นฉันได้โพสต์คำตอบที่ถูกต้อง แต่ทำไมคุณถึงลงคะแนน?
Manjunath

มีกระทู้พร้อมคำตอบดีๆอยู่ที่นี่: stackoverflow.com/questions/14355731/…
ab

คำตอบ:


188
  1. ทำให้กิจกรรมของคุณเป็นไฟล์รายการ: launchMode = "singleInstance"

  2. เมื่อผู้ใช้คลิกใหม่ให้ทำFirstActivity.fa.finish();และเรียกใช้ Intent ใหม่

  3. เมื่อผู้ใช้คลิกแก้ไขให้เรียก Intent ใหม่หรือจบกิจกรรม B

วิธีแรก

ในกิจกรรมแรกของคุณให้ประกาศActivity objectแบบนี้

public static Activity fa;
onCreate()
{
    fa = this;
}

ตอนนี้ใช้วัตถุนั้นในวัตถุอื่นActivityเพื่อทำกิจกรรมแรกให้เสร็จสิ้นเช่นนี้

onCreate()
{
    FirstActivity.fa.finish();
}

วิธีที่สอง

ในขณะที่โทรหากิจกรรมFirstActivityที่คุณต้องการทำให้เสร็จทันทีที่คุณดำเนินการต่อคุณสามารถเพิ่มค่าสถานะขณะโทรได้FirstActivity

intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

แต่การใช้แฟล็กนี้กิจกรรมจะเสร็จสิ้นแม้ว่าคุณจะไม่ต้องการก็ตาม และบางครั้งonBackถ้าคุณต้องการแสดงFirstActivityคุณจะต้องเรียกมันโดยใช้เจตนา


6
ตอบโจทย์มาก .. !!
Vaibhav Vajani

94
คุณกำลังถือการอ้างอิงแบบคงที่ไปยังกิจกรรม สิ่งนี้จะไม่หายไปไหนเว้นแต่คุณจะล้างมันด้วยตนเองจากที่ไหนสักแห่ง -> คุณกำลังสร้างการรั่วไหลของหน่วยความจำ!
DArkO

5
โอเคคุณมี +1 ของฉันสำหรับการคิดนอกกรอบ: D ฉันจะเปลี่ยนเป็น singleTop อย่างไรก็ตามมันก็ยังไม่ใช่ตัวเลือกแรกของฉันเมื่อทำสิ่งที่คล้ายกัน โดยรหัสการล้างข้อมูลฉันหมายถึงวิธีการกำจัดการอ้างอิงแบบคงที่ดังนั้นจึงไม่มีหน่วยความจำรั่วไหล แต่ขึ้นอยู่กับโครงสร้างแอป
DArkO

6
กรุณาไม่มีใครใช้วิธีแก้ปัญหาแรกมันผิดอย่างสมบูรณ์ คุณกำลังข้ามเฟรมเวิร์ก Android ด้วยวิธีที่แฮ็คจริงๆในขณะที่สร้างวัตถุซอมบี้ ใช้ BroadcastReceiver
S-K

1
โซลูชั่นที่ยอดเยี่ยม ทำงานได้ดีมากสำหรับปัญหาของฉันที่ฉันไปจากกิจกรรม A-> B-> C และใน onBackPressed ของ C ฉันกำลังเปิดตัวอินสแตนซ์ใหม่ของ B แต่ถ้าฉันทำ onBackPressed กับอินสแตนซ์ใหม่ของ B มันก็เคย ไปที่อินสแตนซ์เก่าของ B แทนอินสแตนซ์เก่าของ A (สิ่งที่ฉันต้องการ) ดังนั้นฉันจึงทำตามวิธีแรกของคุณใน onBackPressed ของ C และมันทำให้ฉันมีพฤติกรรมที่ฉันต้องการ :) ขอบคุณมาก :)
SoulRayder

88

คุณสามารถทำได้ แต่ฉันคิดว่าคุณไม่ควรทำลายกระแสกิจกรรมปกติ หากคุณต้องการทำกิจกรรมให้เสร็จคุณสามารถส่งการถ่ายทอดจากกิจกรรม B ไปยังกิจกรรม A ได้

สร้างเครื่องรับสัญญาณก่อนเริ่มกิจกรรม B:

BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context arg0, Intent intent) {
        String action = intent.getAction();
        if (action.equals("finish_activity")) {
            finish();
            // DO WHATEVER YOU WANT.
        }
    }
};
registerReceiver(broadcastReceiver, new IntentFilter("finish_activity"));

ส่งการออกอากาศจากกิจกรรม B ไปยังกิจกรรม A เมื่อคุณต้องการจบกิจกรรม A จาก B

Intent intent = new Intent("finish_activity");
sendBroadcast(intent);

ฉันหวังว่ามันจะได้ผลสำหรับคุณ ...


มันแสดงข้อผิดพลาดนี้ "ข้อผิดพลาดทางไวยากรณ์บนโทเค็น AnnotationName คาดไว้แทน" บน "registerReceiver (broadcast_reciever, IntentFilter ใหม่ (" finish_activity "));" มีอะไรผิดปกติ
Behzad

2
"คุณไม่ควรทำลายกระบวนการปกติของกิจกรรม" +1 สำหรับสิ่งนี้
S-K "

11
อย่าลืมยกเลิกการลงทะเบียนbroadcast_receiverด้วยunregisterReceiver()
Jaec


นี่คือทางออก ทำได้ดีนี่
Parinda Rajapaksha

17

นี่เป็นคำถามเพื่อการสื่อสารที่ค่อนข้างเป็นมาตรฐาน แนวทางหนึ่งคือการใช้ ResultReceiver ในกิจกรรม A:

Intent GotoB=new Intent(A.this,B.class);
GotoB.putExtra("finisher", new ResultReceiver(null) {
    @Override
    protected void onReceiveResult(int resultCode, Bundle resultData) {
        A.this.finish();
    }
});
startActivityForResult(GotoB,1);

จากนั้นในกิจกรรม B คุณสามารถทำตามความต้องการได้ดังนี้:

((ResultReceiver)getIntent().getExtra("finisher")).send(1, new Bundle());

ลองอะไรแบบนั้น


6
+1 just, ((ResultReceiver) getIntent (). getParcelableExtra ("finisher")) ส่ง (1, Bundle ใหม่ ());
Hamidreza Sadegh

12

มีแนวทางหนึ่งที่คุณสามารถใช้ในกรณีของคุณได้

ขั้นที่ 1: เริ่มกิจกรรม B จากกิจกรรมก

startActivity(new Intent(A.this, B.class));

ขั้นตอนที่ 2: หากผู้ใช้คลิกที่ปุ่มแก้ไขให้เริ่มกิจกรรม A โดยใช้. FLAG_ACTIVITY_CLEAR_TOPนอกจากนี้ให้ส่งค่าสถานะเป็นพิเศษ

Intent i = new Intent(B.this, A.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.putExtra("flag", "modify");
startActivity(i);
finish();

ขั้นตอนที่ 3: หากผู้ใช้คลิกที่ปุ่มเพิ่มเริ่มกิจกรรม A โดยใช้. FLAG_ACTIVITY_CLEAR_TOPนอกจากนี้ให้ส่งค่าสถานะในพิเศษ FLAG_ACTIVITY_CLEAR_TOPจะล้างกิจกรรมที่เปิดไว้ทั้งหมดจนถึงเป้าหมายและรีสตาร์ทหากไม่มีการกำหนดโหมดการเปิดใช้งานในกิจกรรมเป้าหมาย

Intent i = new Intent(B.this, A.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.putExtra("flag", "add");
startActivity(i);
finish();

ขั้นตอนที่ 4: ตอนนี้onCreate()วิธีการของกิจกรรม A ต้องดึงค่าสถานะนั้น

String flag = getIntent().getStringExtra("flag");
if(flag.equals("add")) {
    //Write a code for add
}else {
    //Write a code for modifying
}

6

เริ่มกิจกรรมของคุณด้วยรหัสคำขอ:

StartActivityForResult(intent,1234);

และคุณสามารถปิดได้จากกิจกรรมอื่น ๆ เช่นนี้:

finishActivity(1234);

เป็นภาษาอะไร ??
Morten Holmgaard

5

ดูคำตอบของฉันกองมากเกินคำถามกิจกรรมก่อนหน้าเสร็จสิ้นทั้งหมด

สิ่งที่คุณต้องการคือเพิ่มไฟล์Intent.FLAG_CLEAR_TOP. แฟล็กนี้ทำให้แน่ใจว่ากิจกรรมทั้งหมดที่อยู่เหนือกิจกรรมเป้าหมายในสแต็กเสร็จสิ้นแล้วและกิจกรรมนั้นจะปรากฏขึ้น

สิ่งที่คุณต้องการก็คือ SINGLE_TOPธง ด้วยสิ่งนี้คุณจะป้องกันไม่ให้ Android สร้างกิจกรรมใหม่หากมีการสร้างไว้แล้วในสแต็ก

เพียงระวังว่าหากสร้างกิจกรรมแล้วเจตนาที่มีแฟล็กเหล่านี้จะถูกส่งด้วยวิธีการที่เรียกว่าonNewIntent(intent)(คุณต้องโอเวอร์โหลดเพื่อจัดการกับกิจกรรมนั้น) ในกิจกรรมเป้าหมาย

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


4

ฉันเพิ่งใช้วิธีแก้ปัญหาของ Nepster และทำงานได้อย่างมีเสน่ห์ มีการปรับเปลี่ยนเล็กน้อยเพื่อเรียกใช้จาก Fragment

ไปยัง Fragment ของคุณ

// sending intent to onNewIntent() of MainActivity
Intent intent = new Intent(getActivity(), MainActivity.class);
intent.putExtra("transparent_nav_changed", true);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

และสำหรับ OnNewIntent () ของกิจกรรมที่คุณต้องการเริ่มต้นใหม่

// recreate activity when transparent_nav was just changed
if (getIntent().getBooleanExtra("transparent_nav_changed", false)) {
    finish(); // finish and create a new Instance
    Intent restarter = new Intent(MainActivity.this, MainActivity.class);
    startActivity(restarter);
}

2

ฉันคิดว่าฉันมีแนวทางที่ง่ายที่สุด ... ในการกดใหม่ใน B ..

Intent intent = new Intent(B.this, A.class);
intent.putExtra("NewClicked", true);
 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

และใน A get it

  if (getIntent().getBooleanExtra("NewClicked", false)) {
        finish();// finish yourself and make a create a new Instance of yours.
      Intent intent = new Intent(A.this,A.class);
      startActivity(intent);
    }

1

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

ฉันเอาชนะonPauseและเรียกfinish()ภายในวิธีการนั้น


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.