ความแตกต่างระหว่าง onStart () และ onResume ()


176

ฉันไม่สามารถรับความหมายของonStart()สถานะการเปลี่ยนแปลง วิธีการที่เรียกว่าเสมอหลังจากที่onResume() onStart()เพราะเหตุใดจึงไม่สามารถonResume()จะเรียกหลังจากที่onRestart()และonCreate()วิธีการเพียงไม่รวมonStart()? จุดประสงค์ของมันคืออะไร?

onStart()ทำไมเราไม่สามารถอยู่ได้โดยไม่ต้อง ฉันยังถือว่ามันซ้ำซ้อน (อาจเป็นเพราะไม่เข้าใจความหมายของมันทั้งหมด)


ดูที่นี่สำหรับระยะเวลาการสมัคร: d.android.com/guide/topics/fundamentals.html
ykatchou

สิ่งนี้เป็นเรื่องง่าย ลองอธิบายสิ่งนี้ด้วย Fragments ตอนนี้นั่นคือการเขียนโปรแกรม Android สำหรับ ya!
Scott Biggs

คำตอบด้านล่างไม่มีรหัสจริงพร้อมคำอธิบาย นี่คือรหัสที่อธิบายด้วยแฟรกเมนต์
Atul

คำตอบ:


306

เหตุใดจึงไม่สามารถเรียกใช้ onResume () หลังจากวิธี onRestart () และ onCreate () เพียงยกเว้น onStart () วัตถุประสงค์ของมันคืออะไร?

ตกลงเนื่องจากคำตอบแรกของฉันค่อนข้างยาวฉันจะไม่ขยายมันต่อไปดังนั้นลองทำสิ่งนี้ ...

public DriveToWorkActivity extends Activity
    implements onReachedGroceryStoreListener {
}

public GroceryStoreActivity extends Activity {}

โปรดทราบ:ฉันจงใจละทิ้งการโทรไปยังสิ่งต่าง ๆ เช่นsuper.onCreate(...)นี้นี่คือรหัสหลอกเพื่อให้สิทธิ์ใช้งานศิลปะแก่ฉันที่นี่ ;)

วิธีการสำหรับ DriveToWorkActivityติดตาม ...

protected void onCreate(...) {
    openGarageDoor();
    unlockCarAndGetIn();
    closeCarDoorAndPutOnSeatBelt();
    putKeyInIgnition();
}

protected void onStart() {
    startEngine();
    changeRadioStation();
    switchOnLightsIfNeeded();
    switchOnWipersIfNeeded();
}

protected void onResume() {
    applyFootbrake();
    releaseHandbrake();
    putCarInGear();
    drive();
}

protected void onPause() {
    putCarInNeutral();
    applyHandbrake();
}

protected void onStop() {
    switchEveryThingOff();
    turnOffEngine();
    removeSeatBeltAndGetOutOfCar();
    lockCar();
}

protected void onDestroy() {
    enterOfficeBuilding();
}

protected void onReachedGroceryStore(...) {
    Intent i = new Intent(ACTION_GET_GROCERIES, ...,  this, GroceryStoreActivity.class);
}

protected void onRestart() {
    unlockCarAndGetIn();
    closeDoorAndPutOnSeatBelt();
    putKeyInIgnition();
}

ตกลงดังนั้นจึงเป็นอีกอันที่ยาว (คนที่เสียใจ) แต่นี่คือคำอธิบายของฉัน ...

onResume() คือเมื่อฉันเริ่มขับรถและ onPause()เมื่อฉันหยุดรถชั่วคราว ดังนั้นฉันจึงขับรถไปถึงแสงสีแดงดังนั้นฉันหยุดชั่วคราว ... แสงเป็นสีเขียวและกลับมาทำงานต่อ แสงสีแดงอีกอันและฉันก็หยุดแล้วก็เป็นสีเขียว onPause() -> onResume() -> onPause() -> onResume()ห่วงเป็นหนึ่งแน่นและเกิดขึ้นหลายครั้งผ่านการเดินทางของฉัน

การวนซ้ำจากการหยุดกลับไปสู่การเริ่มต้นใหม่ (การเตรียมการเดินทางของฉัน) ไปสู่การเริ่มต้นใหม่อาจจะเป็นเรื่องธรรมดาน้อยกว่า ในกรณีหนึ่งฉันเห็นร้านขายของชำและร้านGroceryStoreActivityเริ่มแล้ว (บังคับให้DriveToWorkActivityถึงจุดonStop()) เมื่อผมกลับมาจากร้านผมผ่านไปonRestart()และonStart()จากนั้นให้เริ่มการเดินทางของฉัน

ฉันสามารถใส่รหัสที่อยู่onStart()ในทั้งสองonCreate()และonRestart()ไม่รำคาญที่จะแทนที่onStart()แต่ยิ่งต้องทำระหว่างonCreate() -> onResume()และonRestart() -> onResume()ยิ่งฉันซ้ำสิ่ง

ดังนั้นเพื่อขออีกครั้ง ...

เหตุใดจึงไม่สามารถเรียกใช้ onResume () หลังจากวิธี onRestart () และ onCreate () เพียงยกเว้น onStart ()

หากคุณไม่ลบล้างonStart()สิ่งนี้จะเกิดขึ้นได้อย่างมีประสิทธิภาพ แม้ว่าonStart()วิธีการActivityที่จะถูกเรียกโดยปริยายผลในรหัสของคุณได้อย่างมีประสิทธิภาพหรือonCreate() -> onResume()onRestart() -> onResume()


นี่ก็หมายความว่าทั้งสองonCreate()และonRestart()จะแบ่งปันรหัสทั่วไปจำนวนมากใช่ไหม?
Dheeraj Vepakomma

1
@Dheeraj: ไม่จำเป็น นี่คือรหัสหลอกและตั้งใจจะแสดงให้เห็นว่าแต่ละขั้นตอนของActivityวงจรชีวิตอาจถูกนำมาใช้ ขั้นตอนการสร้างonCreate(...)อาจทำได้ดีมากเมื่อพูดถึงอินสแตนซ์สมาชิกอินสแตนซ์ (องค์ประกอบ UI และอื่น ๆ ) แต่ 'เริ่มใหม่' ไม่ควรต้องทำเช่นนั้น ในความเป็นจริงคนActivitiesส่วนใหญ่ไม่จำเป็นต้องใช้งานมากไปกว่าonCreate(...)นี้onResume()และonPause()วิธีการอื่น ๆ ก็มีให้ใช้ในกรณีที่คุณอาจต้องทำสิ่งอื่น ๆ และที่สำคัญคือต้องเข้าใจว่าควรใส่รหัสไว้ที่ไหน
Squonk

1
นี่คือเหตุผลที่ฉันเกลียด Android API เทียบกับ iOS และแม้แต่ WP7 ... ฉันทำเกมที่ทำงานทั้งสามใน C # และฉันต้องบอกว่าฉันผิดหวังกับ Google และ Android พวกเขาดูเหมือนจะขาดในแผนกออกแบบภาษา / API ฉันหวังว่าระบบปฏิบัติการลินุกซ์โทรศัพท์อื่นจะใช้เวลามากกว่าเพราะฉันจะลงคะแนนให้กับโอเพ่นซอร์สโดยทั่วไป ...
zezba9000

2
@ เวลา: ตกลงมาด้วยการออกแบบที่ดีกว่า คุณจะรับมือกับสถานการณ์บนโทรศัพท์มือถืออย่างไรเมื่อมีคนใช้แอพ (แอพของคุณ) และพวกเขาได้รับโทรศัพท์ทันที? นักออกแบบแอปไม่ได้เรียกActivityวิธีการวงจรชีวิตอย่างชัดเจน- มันเป็นระบบปฏิบัติการ Android ที่ทำมันและมันมีประสิทธิภาพมาก (สมมติว่านักพัฒนาแอปรู้ว่าพวกเขากำลังทำอะไรและใช้รหัสอย่างมีประสิทธิภาพ) หากคุณพัฒนา Android เป็นอย่างมากคุณจะรู้ว่าทำไมสิ่งต่าง ๆ ถึงทำงานเหมือนที่ทำ - มันไม่สมบูรณ์แบบ 100% แต่ก็ค่อนข้างดี
Squonk

9
ฉันคิดว่าคำตอบของ Nilesh ด้านล่างนั้นชัดเจนกว่ามาก ความแตกต่างที่สำคัญระหว่างonStartกับonResumeคือ 'การมองเห็น' และ 'การโต้ตอบของผู้ใช้' คำอุปมาการขับขี่รถยนต์มีความสับสนและไม่ค่อยเป็นประโยชน์
KJ

142

คำตอบสั้น ๆ :

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

นอกจากนี้ onRestart () ยังเป็นที่เข้าใจน้อยที่สุด เราสามารถถามคำถามว่าทำไมไม่ไปที่ onStart () หรือ onResume () หลัง onStop () แทน onRestart () มันจะง่ายต่อการเข้าใจถ้าเราทราบว่า onRestart () บางส่วนเทียบเท่ากับ onCreate () ถ้าส่วนการสร้างถูกละเว้น โดยทั่วไปสถานะทั้งสองจะนำไปสู่ ​​onStart () (เช่นกิจกรรมจะมองเห็นได้) ดังนั้นทั้งสองรัฐต้อง "เตรียม" สิ่งของที่จะแสดง OnCreate มีความรับผิดชอบเพิ่มเติมในการ "สร้าง" สิ่งที่จะแสดง

ดังนั้นโครงสร้างรหัสของพวกเขาอาจพอดีกับสิ่งที่ชอบ:

onCreate()
{
     createNecessaryObjects();

     prepareObjectsForDisplay();
}


onRestart()
{
     prepareObjectsForDisplay();

}

ความสับสนทั้งหมดเกิดขึ้นเนื่องจาก Google เลือกชื่อที่ไม่ง่ายแทนที่จะเป็นชื่อดังนี้:

onCreateAndPrepareToDisplay()   [instead of onCreate() ]
onPrepareToDisplay()            [instead of onRestart() ]
onVisible()                     [instead of onStart() ]
onBeginInteraction()            [instead of onResume() ]
onPauseInteraction()            [instead of onPause() ]
onInvisible()                   [instead of onStop]
onDestroy()                     [no change] 

แผนภาพกิจกรรมอาจตีความได้ว่า:

ระยะเวลากิจกรรม Android


4
เมื่อฉันอธิบายให้นักเรียนฉันใช้บางทีOnInvisible () แทน onStop () และใช้บางที OnDestroy () แทน onDestroy () ชื่อเหล่านี้ใช้ได้ดีกับคำอธิบายที่ฉันพบ คิดว่าฉันไม่ต้องการให้ Google เปลี่ยนชื่อเหล่านี้จริงๆ
เตฟาน Branczyk

ผมชอบชื่อปัญหาของพวกเขาช่วยให้บางความรู้สึกของการเป็นส่วนหนึ่งของ Android API ที่ไร้สาระนี้ ฉันยังมีคำถามโดยทั่วไปเกี่ยวกับวงจรชีวิต ในแผนภาพทั้งหมดแสดงว่ามีเส้นทางจาก onPause โดยตรงไปยัง onResume ฉันไม่คิดว่าฉันเคยเห็นเส้นทางนั้นตามจริงในกรณีใด ๆ ใช้เส้นทางจาก onStop ไปยัง onStart เสมอ อะไรจะทำให้เกิดเส้นทางอื่น
Dewey Vozel

@StephanBranczyk ทำไมคุณถึงใช้ ... () ทำไม "อาจจะ"
Marian Paździoch

1
@Damnum สำหรับคำอธิบายล่าสุดเกี่ยวกับวงจรชีวิตของกิจกรรมฉันขอแนะนำให้คุณดูหลักสูตร Android Udacity ระดับกลางที่สร้างโดย Google ใช้งานได้ฟรีสมมติว่าคุณคลิกที่ปุ่มสีน้ำเงินเพื่อเข้าถึงวัสดุฟรีและไม่ใช่ปุ่มทดลอง (หรือปุ่ม nanodegree) udacity.com/course/developing-android-apps--ud853
Stephan Branczyk

1
@ Damnum ฉันขอแนะนำให้คุณถามคำถามนั้นในฟอรัมความอู้อี้ที่เกี่ยวข้องกับวิดีโอที่คุณดู แต่โดยพื้นฐานแล้วฉันคิดว่ามันขึ้นอยู่กับกล่องโต้ตอบที่ใช้ไม่ว่าจะเป็นกิจกรรมกล่องโต้ตอบหรือกล่องโต้ตอบเท่านั้น
Stephan Branczyk

29

onStart()เรียกเมื่อกิจกรรมปรากฏให้ผู้ใช้เห็น onResume()เรียกว่าเมื่อกิจกรรมจะเริ่มโต้ตอบกับผู้ใช้ คุณอาจต้องการทำสิ่งต่าง ๆ ในกรณีนี้

ดูลิงค์นี้สำหรับการอ้างอิง



10

หนังสือ "Hello, Android, แนะนำแพลตฟอร์มการพัฒนามือถือของ Google" ให้คำอธิบายที่ดีเกี่ยวกับวงจรชีวิตของแอพ Android โชคดีที่พวกเขามีบทเฉพาะทางออนไลน์เป็นข้อความที่ตัดตอนมา ดูกราฟิกในหน้า 39 ใน http://media.pragprog.com/titles/eband3/concepts.pdf

อย่างไรก็ตามหนังสือเล่มนี้เหมาะสำหรับผู้เริ่มต้นใช้งาน Android!


2
รูปภาพสวย ๆ และหนังสือดีๆ แต่ก็ยังไม่ได้รับคำตอบว่าทำไมเราถึงต้องใช้วิธีการ onStart () และสิ่งพิเศษที่เราสามารถทำได้ในนั้นเราไม่สามารถทำได้ใน onResume ()
ยูจีน

8
onStart () ไม่ได้ถูกเรียกถ้าแอพหยุดชั่วคราว แอปของคุณ "หยุดชั่วคราว" หากแอปอื่นได้รับโฟกัส แต่ไม่ปิดบังแอปของคุณอย่างสมบูรณ์ ดังนั้นคุณอาจทำสิ่งต่าง ๆ ในสถานะ "หยุดชั่วคราว" มากกว่าที่คุณจะทำในสถานะ "หยุด" ดังนั้นคุณอาจทำสิ่งที่แตกต่างกันหากแอปของคุณ "หยุดชั่วคราว" จากสถานะหยุดชั่วคราวกว่าที่คุณจะทำหากแอปของคุณ "เริ่มต้น" จากสถานะหยุดหรือเริ่มต้นสมบูรณ์ มันช่วยได้ไหม
Martin Booka Weser

7

showDialog()ตัวอย่างซ่าโดยเฉพาะอย่างยิ่งคือเมื่อคุณตัดสินใจที่จะแสดงให้เห็นถึงการบริหารจัดการโต้ตอบจากกิจกรรมการใช้ หากผู้ใช้หมุนหน้าจอในขณะที่กล่องโต้ตอบยังคงเปิดอยู่ (เราเรียกสิ่งนี้ว่า "การเปลี่ยนแปลงการกำหนดค่า") จากนั้นกิจกรรมหลักจะผ่านวงจรชีวิตทั้งหมดที่สิ้นสุดไปจนหมดonDestroy()จะถูกสร้างขึ้นใหม่และย้อนกลับไปตลอดวงจร สิ่งที่คุณไม่อาจคาดหวัง แต่เป็นที่onCreateDialog()และonPrepareDialog()(วิธีการที่เรียกว่าเมื่อคุณทำshowDialog()และตอนนี้อีกครั้งโดยอัตโนมัติเพื่อสร้างโต้ตอบ - โดยอัตโนมัติเพราะมันเป็นกล่องโต้ตอบจัดการ) จะเรียกว่าระหว่าง และonStart() onResume()ประเด็นที่นี่คือการโต้ตอบไม่ครอบคลุมเต็มหน้าจอและทำให้ส่วนหนึ่งของกิจกรรมหลักที่มองเห็นได้ มันเป็นรายละเอียด แต่มันก็สำคัญ!


7

onStart()

  1. เรียกว่าหลังจาก onCreate (Bundle) หรือหลัง onRestart () ตามด้วย onResume ()()
  2. คุณสามารถลงทะเบียน BroadcastReceiver ได้ onStart()การตรวจสอบการเปลี่ยนแปลงที่มีผลต่อ UI ของคุณคุณต้องยกเลิกการลงทะเบียนใน onStop ()
  3. คลาสที่ได้รับมาจะต้องเรียกใช้ผ่านเมธอดนี้ หากพวกเขาทำไม่ได้ข้อยกเว้นจะถูกโยน

onResume()

  1. เรียกว่าหลังจาก onRestoreInstanceState (Bundle), onRestart () หรือ onPause ()
  2. เริ่มต้นภาพเคลื่อนไหวเปิดอุปกรณ์พิเศษเข้าถึง (เช่นกล้อง)

onStart() โดยปกติแล้วจะส่งงานไปยังเธรดพื้นหลังซึ่งมีค่าส่งคืนดังนี้:

  • START_STICKYรีสตาร์ทโดยอัตโนมัติหากถูกฆ่าเพื่อให้ใช้งานได้

  • START_REDELIVER_INTENT สำหรับการรีสตาร์ทอัตโนมัติและลองอีกครั้งหากบริการถูกฆ่าก่อน stopSelf ()

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

onResume() ถูกเรียกโดยไม่ต้อง onStart()เมื่อกิจกรรมดำเนินการต่อจากพื้นหลัง

สำหรับรายละเอียดเพิ่มเติมคุณสามารถเยี่ยมชมAndroid_activity_lifecycle_gotchaและActivity Lifecycle


ที่จริงแล้วฉันขึ้นไปบนแล้วเมื่อแอปของฉันไปที่พื้นหลัง
เดดฟิช

5

หวังว่าคำอธิบายง่ายๆ: -

onStart () -> เรียกเมื่อกิจกรรมสามารถมองเห็นได้ แต่อาจไม่อยู่ในเบื้องหน้า (เช่น AlertFragment อยู่ด้านบนหรือกรณีการใช้งานที่เป็นไปได้อื่น ๆ )

onResume () -> เรียกเมื่อกิจกรรมอยู่เบื้องหน้าหรือผู้ใช้สามารถโต้ตอบกับกิจกรรม


4

onStart()หมายถึงการActivityเข้าสู่สถานะที่มองเห็นและการสร้างรูปแบบ แต่ไม่สามารถโต้ตอบกับรูปแบบกิจกรรมนี้

Resume() หมายความว่าตอนนี้คุณสามารถโต้ตอบกับเค้าโครงกิจกรรมได้


1

โปรดทราบว่ามีสิ่งต่าง ๆ ที่เกิดขึ้นระหว่างการเรียกไปยัง onStart () และ onResume () คือ onNewIntent () ซึ่งฉันได้ค้นพบอย่างเจ็บปวด

หากคุณใช้การตั้งค่าสถานะ SINGLE_TOP และคุณส่งข้อมูลบางอย่างไปยังกิจกรรมของคุณโดยใช้ความตั้งใจพิเศษคุณจะสามารถเข้าถึงได้เฉพาะใน onNewIntent () ซึ่งถูกเรียกใช้หลังจาก onStart () และก่อน onResume () ดังนั้นโดยปกติคุณจะใช้ข้อมูลใหม่ (อาจมีการแก้ไขเท่านั้น) จาก extras และตั้งค่าให้กับสมาชิกชั้นเรียนบางคนหรือใช้ setIntent () เพื่อกำหนดเจตนาใหม่เป็นเจตนากิจกรรมดั้งเดิมและประมวลผลข้อมูลใน onResume ()


0

อ้างอิงถึงhttp://developer.android.com/training/basics/activity-lifecycle/starting.html

onResume()เรียกว่าก่อนที่กิจกรรมจะเริ่มโต้ตอบกับผู้ใช้ ณ จุดนี้กิจกรรมจะอยู่ที่ด้านบนสุดของสแต็กกิจกรรมโดยอินพุตของผู้ใช้จะเข้าสู่กิจกรรม onPause()ตามเสมอโดย

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


0

ไม่แน่ใจว่านี่นับเป็นคำตอบหรือไม่ แต่นี่คือวิดีโอ YouTube จากหลักสูตรของ Google (การพัฒนาแอป Android ด้วย Kotlin) ที่อธิบายความแตกต่าง

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