หลังจากที่ได้ฝึกเขียน App บน Android มาเกือบ 2 ปี ด้วยการอ่านตำราบ้าง ดูตามเว็บบ้าง อ่าน Reference จากเว็บ Android Developer บ้าง StackOverflow.com บ้าง ถามชาวบ้านเอาบ้าง และมั่วเอาบ้าง แต่ไม่เคยได้ปรับพื้นฐานที่ควรจะแม่นก่อน ซึ่งเป็นสิ่งสำคัญมาก และเป็นพื้นฐานมาก ๆ ของการพัฒนา App บน Android นั่นก็คือ Activity Lifecycle
ช่วงนี้เลยกันเวลาบางส่วน หยุดทำ App เพื่อมาปรับพื้นฐานให้กับตัวเอง
สำหรับเรื่อง Activity Lifecycle นั้น ผู้พัฒนา App ส่วนใหญ่ ได้จับต้องกับมันแล้ว เพียงแต่ไม่รู้ตัว บ้างก็รู้นั่นแหล่ะ แต่ไม่เคยลงรายละเอียด และทำความเข้าใจมันอย่างถ่องแท้
สำหรับบทความตอนนี้ ก็เลยจะเขียนเกี่ยวกับเรื่อง Activity Lifecycle ในอีกมุมมองนึง ที่ผมจะสรุปมาให้อ่านกัน
List of contents
- Activity Lifecycle
- Activity Lifecycle + System Callback
- Activity Lifecycle + System Callback เมื่อกลับสู่ App ที่ถูกบดบังบางส่วน
- Activity Lifecycle + System Callback เมื่อกลับสู่ App ที่ถูกบดบังจนหมด (ยังเปิดอยู่)
- Activity Lifecycle + System Callback เมื่อกลับสู่ App หลังจากโดนทำลาย
- Activity Lifecycle + System Callback Summary
- สรุปกันดีกว่า
Activity Lifecycle
คงเคยเห็น Activity Lifecycle ในรูปแบบของ Flowchart รูปนี้กันมาบ้างแล้ว

รูปจาก : http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
ทบทวนกันนิดนึง…
- Activity Launched คือสถานะที่เกิดขึ้นเมื่อ User เปิดใช้งาน App ซึ่ง Activity ที่ถูกกำหนดให้ Launch ได้ของ App นั้น ๆ จะถูกเรียกใช้งาน ซึ่งจะทำให้ Method onCreate(), onStart() และ onResume() ใน Activity นั้น ทำงาน
- Activity running คือสถานะที่ User กำลังเล่นอยู่บน App
- หากว่า Activity ถูกบดบังบางส่วน จะทำให้ Method onPause() ทำงาน หากกลับเข้าสู่ App จะทำให้ Method onResume() ทำงาน
- และถ้าถูกบนบังจนหมด จะทำให้ Method onStop() ทำงานต่อจาก onPause() หากกลับเข้าสู่ App จะทำให้ Method onRestart(), onStart() และ onResume() ทำงาน
- และเมื่อ User ออกจาก App จะทำให้ Method onDestroy() ทำงาน
- Activity shut down คือสถานะที่ Activity ถูกเลิกใช้งานแล้ว
- App process killed คือสถานะที่ App ถูก Kill โดยระบบ (เฉพาะกรณีเมื่อ Activity อยู่ในสถานะ Stop) เนื่องจากระบบต้องการ Memory หาก User กลับเข้าสู่ App จะทำกลับไปเริ่มต้นทำงานใหม่ที่ Method onCreate()
พยายามสรุปย่อให้สั้น โดยไม่ตกหล่นแล้ว สั้นได้เท่านี้…
ยังงงอยู่ใช่ไม๊!?
งั้นเอาใหม่… ลองดูรูปต่อไปนี้

รูปจาก : http://developer.android.com/training/basics/activity-lifecycle/starting.html#lifecycle-states
ซึ่งมันก็เหมือนกับรูปแรกนั่นแหล่ะ แต่เอามาเขียนใหม่เป็นลักษณะแบบพีรามิด ให้เราเข้าใจง่ายขึ้น (มั๊ง)
ในรูปนี้ ทาง Google พยายามอธิบายในลักษณะของ State และการทำงานแบบ Callback!! ต่างจากรูปแรก ที่อธิบายทุกอย่างรวมกันอยู่ และได้อธิบายว่า Android นั้น การทำงานต่างจากภาษาโปรแกรมอื่น ๆ ที่มักจะเริ่มต้นที่ Method main() แต่เป็นการทำงานในลักษณะ Callback จากระบบ
ถ้าจิ้มตาม Link ไปดู จะเห็นว่า Google ได้อธิบายไว้เป็น 3 State ดังนี้
- Resumed (หรือเรียกว่า Running ก็ได้) คือ State ที่อยู่เบื้องหน้า User กำลังเล่นกับ App อยู่ (กล่องสีเขียว)
- Paused คือ State ที่ App ถูกบดบังบางส่วน (กล่องสีเหลือง)
- Stoped คือ State ที่ App ถูกบดบังทั้งหมด (กล่องสีส้ม)
ส่วน Callback นั้น ลองสังเกตุในรูปด้านบน Method ต่าง ๆ นั้น ไม่ใช้อยู่ ๆ มันทำงานขึ้นมาเองได้ แต่มันถูก Callback มาจากระบบนั่นเอง
สำหรับการทำงานแบบ Callback นั้น ถ้าใครรู้จักอยู่แล้ว จะร้องอ๋อทันที แต่ถ้าใครไม่รู้จัก ลองไปอ่านบทความเกี่ยวกับ Callback ที่ผมเคยเขียนไว้ดูก่อนก็ได้ แต่เป็นภาษาโปรแกรมภาษาอื่นนะ ดูเป็นแนวคิดก็พอ จะได้เข้าใจคำว่า Callback
สำหรับผู้ที่มาจากภาษา Visual Basic หรือภาษาอื่น ๆ ที่มีการทำงานในลักษณะ Event-Driven นั้น คงรู้จักคำว่า Event ดี ซึ่ง Event นั่นแหล่ะ คือ Callback ที่เรียกมาจากระบบ
ยังไม่ค่อยเคลียร์ใช่ไม๊ งั้นดูใหม่…
Activity Lifecycle + System Callback
ลองวาดรูปออกมาให้ดู ให้เห็นการทำงานของ Activity ร่วมกับระบบ ออกมาเป็น ดังนี้

ครึ่งล่าง คือฝั่งของ System ส่วนครึ่งบน เป็นฝั่งของ Activity
- เมื่อ User เข้าสู่ App ระบบจะ Callback Method onCreate() ใน Activity ของเรา เมื่อ Method ทำงานเสร็จแล้ว ก็จะกลับไปที่ระบบ และเข้าสู่สถานะ Created
- เมื่ออยู่ในสถานะ Created ระบบจะ Callback Method onStart() ใน Activity ของเรา เมื่อ Method ทำงานเสร็จแล้ว ก็จะกลับไปที่ระบบ และเข้าสู่สถานะ Started
- เมื่ออยู่ในสถานะ Started ระบบจะ Callback Method onResume() ใน Activity ของเรา เมื่อ Method ทำงานเสร็จแล้ว ก็จะกลับไปที่ระบบ และเข้าสู่สถานะ Resumed
ที่สถานะ Resumed หรือ Running User ก็จะมองเห็น และเล่นอยู่บน App นั่นเอง
- เมื่ออยู่ในสถานะ Resumed หรือ Running แล้วมีอะไรมาบดบัง App เรา ระบบจะ Callback Method onPause() ใน Activity ของเรา เมื่อ Method ทำงานเสร็จแล้ว ก็จะกลับไปที่ระบบ และเข้าสู่สถานะ Paused
- เมื่ออยู่ในสถานะ Paused แล้ว App เราถูกบดบังจนหมด ระบบจะ Callback Method onStop() ใน Activity ของเรา เมื่อ Method ทำงานเสร็จแล้ว ก็จะกลับไปที่ระบบ และเข้าสู่สถานะ Stoped
- เมื่ออยู่ในสถานะ Stoped แล้ว App เราถูกปิด ระบบจะ Callback Method onDestroy() ใน Activity ของเรา เมื่อ Method ทำงานเสร็จแล้ว ก็จะกลับไปที่ระบบ และเข้าสู่สถานะ Destroyed
สังเกตุว่า ทั้ง 6 Method นั้น มี “ระบบ” เป็นผู้เรียกใช้งาน ถึงเรียกว่า Callback นั่นเอง
เข้าใจมากขึ้นกันไม๊อ่ะ…
Activity Lifecycle + System Callback เมื่อกลับสู่ App ที่ถูกบดบังบางส่วน
กรณีที่ App เปิดอยู่ และถูกบดบังบางส่วน จะเข้าสู่สถานะ Paused ตามที่ได้อธิบายไปแล้วด้านบน หากว่ายังไม่ถูกปิด และ User กลับเข้ามาสู่ App อีกครั้ง ระบบจะ Callback Method onResume() ใน Activity ของเรา ลองดูรูปต่อไปนี้

ก็คือเส้นสีส้มที่เพิ่มขึ้นมานั่นเอง…
Activity Lifecycle + System Callback เมื่อกลับสู่ App ที่ถูกบดบังจนหมด (ยังเปิดอยู่)
กรณีที่ App เปิดอยู่ และถูกบดบังจนหมด ก็จะเข้าสู่สถานะ Stoped หากว่ายังไม่ถูกปิด และ User กลับเข้ามาสู่ App อีกครั้ง ระบบจะ Callback Method onRestart() ใน Activity ของเรา แล้วตามด้วย Method onStart() ลองดูรูปต่อไปนี้

ก็คือตามเส้นสีส้มนั่นเอง…
แล้วกรณีไหนบ้างล่ะ ที่จะทำให้เข้าสู่สถานะ Stoped
- User กดปุ่ม Recent Apps หรือ Home
- App สั่งให้เปิด Activity ใหม่
- เมื่อมีคนโทรเข้า
- มี App อื่นสลับขึ้นมาทำงาน
พออยู่ในสถานะ Stoped แล้วกลับมาใหม่ ทำให้เกิด onRestart() จากไหนบ้าง
- กดเปิด App จาก Icon หรือ Recent Apps
- สลับกลับมายัง Activity อื่น
- สลับกลับมาจาก App อื่น
Activity Lifecycle + System Callback เมื่อกลับสู่ App หลังจากโดนทำลาย
กรณีที่ App ถูกทำลายโดยระบบ (เมื่ออยู่ในสถานะ Stoped และระบบต้องการ Memory เพิ่ม) ไม่ได้ถูกปิดโดยปกติจาก User หรือ App สิ้นสุดการทำงาน จะมี Callback Method ของ Activity อีก 2 ตัวที่น่าสนใจให้เราใช้ ลองดูรูปต่อไปนี้

สังเกตที่เส้นสีส้ม หลังจากเกิด onPause() ก่อน จะเห็นว่า มี Method onSaveInstantState() เพิ่มขึ้นมา โดย Method นี้ จะมี 1 Parameter เป็นชนิด Bundle ซึ่งเก็บข้อมูลในลักษณะ key-value pairs ตรงนี้ล่ะ เราสามารถฝากข้อมูลต่าง ๆ ลงไปได้
เมื่อกลับเข้าสู่ App หลังจากโดนทำลาย จะเริ่มต้นการทำงานที่ onCreate() ใหม่เลย แต่ที่ onCreate() จะมี Parameter ชนิด Bundle ส่งมาด้วย ซึ่งเราสามารถนำมาเช็คได้ว่า Method onCreate() ที่ระบบ Callback มานั้น เป็นการเปิด App ขึ้นมา หรือกลับมาใหม่หลังโดนทำลาย
กรณี App เปิดขึ้นมาใหม่ แต่ไม่ใช่การกลับมาหลังถูกทำลาย ตัวแปร Bundle จะมีค่าเป็น Null ระวังตรงนี้ด้วย
และเส้นสีส้ม หลังจากเกิด onStart() จะมี Method onRestoreInstantState() เพิ่มขึ้นมา ซึ่งจะถูกระบบ Callback มาให้ เฉพาะกรณีที่กลับมาใหม่หลังโดนทำลายเท่านั้น ซึ่งจะมี Parameter ชนิด Bundle ส่งมาด้วย เช่นเดียวกับ Method onCreate() (และเป็นค่าเดียวกันนั่นเอง)
ซึ่งเมื่อเราตรวจสอบได้แล้วว่า เป็นการกลับเข้าสู่ App ใหม่ หลังจากโดนทำลาย เราก็สามารถนำข้อมูลที่ฝากไว้ที่ Bundle กลับคืนสู่ App เพื่อทำงานต่อได้ โดย User ไม่รู้สึกว่า App ได้เริ่มต้นทำงานใหม่ นั่นเอง
Activity Lifecycle + System Callback Summary
เมื่อนำมาเขียนรวมกัน จะได้รูปดังนี้

คงไม่ต้องอธิบายเน๊อะ อธิบายไปในแต่ละส่วนหมดแล้ว
สรุปกันดีกว่า
จากที่อธิบายข้างบนว่า การทำงานของ Activity นั้น เป็นการทำงานโดยเริ่มต้นที่ System ทำการ Callback มายังแต่ละ Method ของ Activity เรา
เมื่อเข้าใจว่า Activity ใน App ของเรา ทำงานในลักษณะ Callback โดย System แล้ว (ไม่ใช่ใครที่ไหนมา Call Method เรา) ทำให้เราเข้าใจ Activity Lifecycle มากขึ้น รวมถึง State การทำงานต่าง ๆ ทำให้เรา Implement code ของเรา ที่ Method ต่าง ๆ ได้ถูกต้อง เหมาะสม และได้ประสิทธิภาพของ App ที่ดีขึ้นนั่นเอง
ไม่ใช่เอะอะอะไรก็ใส่ใน onCreate() อย่างเดียว อย่างที่ผมเคยเป็น!!
สุดท้าย…
Callback นั้น สำคัญมากนะ ใครยังไม่เข้าใจ ไปต่อลำบากมากนะครับ ไม่ใช่เฉพาะบน Android นะ ภาษาโปรแกรมอื่น ๆ ก็มี หรือทำงานในลักษณะ Callback เยอะแยะแล้ว
แถมอีกนิด… สำหรับใครที่อยากทำความเข้าใจเรื่อง Activity Lifecycle เพิ่มเติม ลองอ่านที่ มารู้จักรอบชีวิตของ Android กัน มันไม่เหมือนใครหรอกนะ ซึ่งคุณ Mart Tanathip ได้อธิบายไว้ในเว็บได้ดีมาก ลองตามไปอ่านกันดูนะครับ
Permalink
เพิ่มหัวข้อ Activity Lifecycle + System Callback เมื่อกลับสู่ App ที่ถูกบดบังบางส่วน และอัพเดตรูป Summary เพื่อความครบถ้วนนะครับ