ความแตกต่างระหว่าง onPause () และ onStop () ของ Android Activites คืออะไร?


149

จาก android doc ที่นี่http://developer.android.com/reference/android/app/Activity.htmlกล่าวว่าจะมีการเรียก 'กิจกรรมเข้าสู่เบื้องหน้า' onPause()และ 'กิจกรรมจะไม่ปรากฏอีกต่อไป' จะเรียกใช้onStop()จะเรียก

'กิจกรรมเข้าสู่เบื้องหน้า' ไม่เหมือนกับ 'กิจกรรมไม่ปรากฏอีกต่อไป' หรือไม่ คุณช่วยกรุณาบอกฉันว่าอะไรคือความแตกต่างระหว่างพวกเขา?


17
+1 สำหรับคำถามที่ยอดเยี่ยม นอกจากนี้pausedกิจกรรมยังมีชีวิตอยู่อย่างสมบูรณ์ (จะรักษาข้อมูลสถานะและสมาชิกทั้งหมดและยังคงติดอยู่กับตัวจัดการหน้าต่าง) stoppedกิจกรรมยังคงรักษารัฐและสมาชิกข้อมูลทั้งหมด window managerแต่ไม่แนบไป
ateiob

คำตอบ:


107

ไม่ถ้ากิจกรรมบางอย่างเข้ามาอยู่เบื้องหน้านั่นไม่ได้แปลว่ากิจกรรมอื่นนั้นจะมองไม่เห็นอย่างสมบูรณ์ พิจารณากรณีต่อไปนี้:

กิจกรรมกับธีม Theme.Dialog

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

นั่นทำให้คำถามว่ากิจกรรมใดที่ถือว่าทึบอย่างสมบูรณ์และครอบคลุมทั้งหน้าจอและไม่ใช่ การตัดสินใจนี้ขึ้นอยู่กับหน้าต่างที่มีกิจกรรม หากหน้าต่างมีการตั้งค่าสถานะwindowIsFloatingหรือแสดงwindowIsTranslucentว่ากิจกรรมนั้นไม่ทำให้สิ่งที่มองไม่เห็นไม่เช่นนั้นจะทำและจะonStop()ถูกเรียก รหัสที่เกี่ยวข้องสามารถพบได้ในcom.android.server.am.ActivityRecord:

fullscreen = ent != null && !ent.array.getBoolean(
        com.android.internal.R.styleable.Window_windowIsFloating, false)
        && !ent.array.getBoolean(
        com.android.internal.R.styleable.Window_windowIsTranslucent, false);

10
+1 สำหรับคำอธิบายที่ดีโดยเน้นที่การมองเห็นบางส่วนหรือทั้งหมด (เป็น) มันจะน่าสนใจที่จะรู้ว่าร้อยละเกณฑ์ของหน้าจอที่ทำให้ตัดสินใจระหว่าง Android และonPause() onStop()มันเป็น 100% หรือไม่ หากมองเห็นเพียงหนึ่งพิกเซลจากกิจกรรมก่อนหน้านี้จะยังคงอยู่onPause()หรือไม่
ateiob

3
@ateiob มันไม่ได้พูดที่ไหนเลย แต่ฉันก็คิดอย่างนั้น อย่างไรก็ตามมักจะเห็นได้ชัดเพราะกิจกรรมส่วนใหญ่ที่ไม่เต็มหน้าจอเพียงแค่ใช้หนึ่งในระบบที่มีสไตล์สำหรับการโต้ตอบ
Malcolm

1
แปลก แต่ในแอปพลิเคชันของฉันonPause()ไม่ได้ถูกเรียกเลยเมื่อมีกล่องโต้ตอบปรากฏขึ้น onPause()ถูกเรียกเมื่อฉันกดปุ่มโฮมเท่านั้น เป็นไปได้อย่างไร?
ateiob

นี่ควรเป็นคำตอบที่ถูกต้อง ยังไงก็ตามสิ่งที่สำคัญคือกล่องโต้ตอบหรือกิจกรรม
GMsoF

3
@GMsoF กิจกรรม นั่นคือประเด็นหลัก: ไม่ใช่ว่าทุกกล่องโต้ตอบจะเป็นกล่องโต้ตอบ คุณสามารถทำให้กิจกรรมดูเหมือนโต้ตอบดังนั้นจริง ๆ แล้วมีขนาดเล็กกว่าทั้งหน้าจอ
Malcolm

38

หากคุณยังคงเห็นส่วนใดส่วนหนึ่งของมัน ( Activityการทำงานเบื้องหน้าไม่ได้ครอบคลุมทั้งหน้าจอหรือมีความโปร่งใส) onPause()จะถูกเรียกใช้ หากคุณไม่เห็นส่วนใดส่วนหนึ่งของมันonStop()จะถูกเรียก

ตัวอย่างเช่นกล่องโต้ตอบ ** อาจไม่ครอบคลุมทั้งหมดก่อนหน้านี้Activityและนี่จะเป็นเวลาสำหรับonPause()จะถูกเรียก

** ฉันไม่ได้อ้างอิงถึงกล่องโต้ตอบ Android ที่นี่ แต่เป็นแนวคิดเกี่ยวกับสิ่งที่โผล่ขึ้นมาและปิดบังส่วนหนึ่งของหน้าจอผู้ใช้เท่านั้น บันทึกนี้ได้รับการเพิ่มเพื่อชี้แจงตามความคิดเห็นจาก @GMsoF ด้านล่าง


33
NO นี่เป็นสิ่งที่ทำให้เข้าใจผิด ไดอะล็อกที่แสดงจะไม่เรียก onPause () เนื่องจากไดอะล็อกใช้บริบทของกิจกรรมปัจจุบันพิจารณากิจกรรมที่ยังมีชีวิตอยู่
GMsoF

6
@GMsoF ดูเหมือนว่าเมื่อฉันพูดโต้ตอบคุณคิดว่าฉันหมายถึงDialogเช่นเดียวกับในระดับ Android แม้ว่าสิ่งที่ฉันได้รับเป็นสิ่งที่คลุมเครือส่วนแรกActivityเพื่อแสดงให้เห็นถึงแนวคิดที่ว่าสิ่งใหม่ทั้งหมดActivityไม่จำเป็นต้องปกปิดอย่างสมบูรณ์ก่อนหน้านี้
nicholas.hauschild

11

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


5
สิ่งที่ไดอะล็อกอาจทำให้เข้าใจผิด ให้กล่องโต้ตอบคำเตือนปรากฏขึ้นจากเธรด UI หลักของกิจกรรมนี้ onPause () จะไม่ถูกเรียกในกรณีนี้ หากกล่องโต้ตอบนี้ปรากฏขึ้นจากกิจกรรมอื่นหรือแอปอื่น
Sam003

1
@Zhisheng - ฉันเห็นด้วยกับความคิดเห็นของคุณ ฉันเป็นเพียงการถอดความคู่มือหัวข้อกิจกรรม : "onPause()จะเรียกว่าเมื่ออุปกรณ์ไปนอนหลับหรือเมื่อปรากฏโต้ตอบ" เนื่องจากเธรดนี้มีความชัดเจนแม้ว่าการโต้ตอบไม่จำเป็นต้องหมายความว่ากิจกรรมจะหยุดชั่วคราว (แม้ว่าจะเป็นการพูดกิจกรรมที่แสดงเป็นไดอะล็อก )
Ted Hopp

9

ในทางปฏิบัติเราควรพิจารณาถึงความแตกต่างระหว่าง“ onPause ()”และ“ onPause () + onStop ()”

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

ในทางกลับกันหากมีกิจกรรมใหม่เกิดขึ้นและครอบครองแบบเต็มหน้าจอเพื่อให้กิจกรรมการทำงานก่อนหน้านี้ของคุณหายไป ในกรณีนี้กิจกรรมที่ทำงานก่อนหน้านี้ของคุณจะถูกย้ายไปที่ Back Stack ที่นี่ onPause () + onStop () ถูกเรียก

ถึงสรุป -

onPause () - หน้าจอบางส่วนถูกปกคลุมด้วยกิจกรรมใหม่อื่น ๆ กิจกรรมจะไม่ย้ายไปที่ Back Stack

onPause () + onStop () - หน้าจอเต็มไปด้วยกิจกรรมใหม่อื่น ๆ กิจกรรมถูกย้ายไปที่ Back Stack

ทราบข้อมูลเพิ่มเติม about- กลับกอง


0

ในคำกระชับ:

onStop()ของกิจกรรมวัฏจักรชีวิตของกิจกรรมก่อนหน้านี้จะถูกเรียกใช้เมื่อมีการแสดงกิจกรรมอื่น เมื่อคุณมีบทสนทนาที่ด้านบนของกิจกรรมonPause()จะมีการเรียกใช้

หมายเหตุ : กิจกรรมคือองค์ประกอบเหล่านั้นซึ่งเต็มหน้าจอของคุณ

หมายเหตุ : การสนทนาไม่ใช่กิจกรรมเนื่องจากไม่เต็มหน้าจออย่างสมบูรณ์


0

ฉันประสบปัญหามากมายเกี่ยวกับวิธีการ onPause และ onStop และด้วยเหตุนี้ฉันจะเคลียร์สามสถานการณ์ที่ฉันเจอ -
1เมื่อคุณคลิกที่ปุ่มแอพล่าสุดไม่มีวิธีวงจรชีวิตเรียกว่า แต่ onWindowFocusChanged (บูลีน hasFocus) เรียกว่ามีค่าโฟกัส ส่งผ่านเป็นเท็จ ใน Android เวอร์ชันก่อนหน้า 5 วิธี onPause เคยถูกเรียกใช้เมื่อกดปุ่มแอพล่าสุด

2.เมื่อป๊อปอัปเช่นกิจกรรมปรากฏขึ้นเหนือกิจกรรมของคุณดังที่Malcolmพูดถึงปุ่ม onPause จะถูกเรียกใช้ หากมีการเรียกกิจกรรมใหม่ที่ใช้ทั้งหน้าจอจะมีการเรียกใช้ onStop ในกิจกรรมก่อนหน้า ช่องโต้ตอบการอนุญาตของ Android ทำให้กิจกรรมของคุณเรียก onPause

3หากหน้าจอหมดเวลากับกิจกรรมของคุณจะมีการเรียกใช้ onPause หลังจากบางครั้งถ้าคุณจะไม่เปิดหน้าจอจากนั้นหยุดบนจะถูกเรียก

สิ่งหนึ่งที่สำคัญที่กล่าวถึงโดยateiobที่ทำให้คำตอบเสร็จสมบูรณ์

กิจกรรมที่หยุดชั่วคราวนั้นยังมีชีวิตอยู่อย่างสมบูรณ์ (จะรักษาข้อมูลสถานะและสมาชิกทั้งหมดและยังคงอยู่กับโปรแกรมจัดการหน้าต่าง) กิจกรรมที่หยุดยังคงข้อมูลสถานะและสมาชิกทั้งหมดไว้ แต่จะไม่เชื่อมต่อกับตัวจัดการหน้าต่างอีกต่อไป


หวังว่ามันจะช่วย


0

เมื่อใดก็ตามที่กิจกรรมใหม่เริ่มกิจกรรมก่อนหน้านี้ onPauseจะถูกท้าทายในทุกสถานการณ์

จริงๆแล้วจะมีสองสถานการณ์:

1- ส่วนหนึ่งของกิจกรรมก่อนหน้านี้สามารถมองเห็นได้หรือกิจกรรมใหม่มีความโปร่งใส: เท่านั้น onPauseจะถูกเรียกเท่านั้น

2- กิจกรรมก่อนหน้านี้ได้รับการครอบคลุมโดยกิจกรรมใหม่: ทั้งonPauseและonStopจะถูกเรียก

---- ดีที่จะระบุบางบันทึก:

หมายเหตุ 1: ถ้าไดอะล็อกเริ่มต้นที่ด้านบนของกิจกรรมที่ไม่มีonPauseหรือonStopจะถูกเรียก

หมายเหตุ 2: ถ้าเป็นกิจกรรมที่มีการตั้งค่าชุดรูปแบบเป็นไดอะล็อกพฤติกรรมจะเหมือนกับกิจกรรมปกติ

หมายเหตุ 3: onPauseเห็นได้ชัดโต้ตอบระบบเช่นโต้ตอบได้รับอนุญาตตั้งแต่ขนมหวานจะทำให้เกิด


-5

ใช่ฉันพยายามเข้าใจและฉันสามารถอธิบายด้านล่างนี้:

มี 2 ​​กิจกรรมคือ ActivityA & ActivityB

public class ActivityA extends Activity implements OnClickListener {

// button
private Button mBtnChangeActivity;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_a);
    initialize();
    setEvent();
}

private void initialize() {
    Log.i("Activity A", "Initialize()");
    mBtnChangeActivity = (Button) findViewById(R.id.btn_change_activity);
}

private void setEvent() {
    Log.i("Activity A", "setEvent()");
    mBtnChangeActivity.setOnClickListener(this);
}

@Override
protected void onStart() {
    super.onStart();
    Log.i("Activity A", "onStart");
}

@Override
protected void onResume() {
    super.onResume();
    Log.i("Activity A", "onResume");
}

@Override
protected void onPause() {
    super.onPause();
    Log.i("Activity A", "onPause");
}

@Override
protected void onStop() {
    super.onStop();
    Log.i("Activity A", "onStop");
}

@Override
protected void onDestroy() {
    super.onDestroy();
    Log.i("Activity A", "onDestroy");
}

@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.btn_change_activity:
        Intent activityB = new Intent(this, ActivityB.class);
        startActivity(activityB);
        break;
    default:
        break;
    }
}

นี่คือกิจกรรม B. ติดตามความคิดเห็นของฉันในรหัส

public class ActivityB extends Activity implements OnClickListener {

// button
private Button mBtnChangeActivity;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_a);
    initialize();
    setEvent();
    // if call finish() here, activityA will don't stop, just pause
    // Activity A will call onStop() when Activity B call onStart() method
    finish();
}

private void initialize() {
    Log.i("Activity B", "Initialize()");
    mBtnChangeActivity = (Button) findViewById(R.id.btn_change_activity);
}

private void setEvent() {
    Log.i("Activity B", "setEvent()");
    mBtnChangeActivity.setOnClickListener(this);
}

@Override
protected void onStart() {
    super.onStart();
    Log.i("Activity B", "onStart");
}

@Override
protected void onResume() {
    super.onResume();
    Log.i("Activity B", "onResume");
}


@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.btn_change_activity:
        finish();
        break;
    default:
        break;
    }
}
}

ฉันหวังว่านี่ชัดเจน


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