เรื่องเล่าจาก Instant Run สุดเทพบน Android Studio
สำหรับ Android Dev แล้ว เมื่อได้ยินคำว่า Instant Run เมื่อไหร่ ส่วนใหญ่ก็จะคงรู้จักกับชื่อนี้กันเป็นอย่างดี เพราะมันคือหนึ่งในฟีเจอร์ของ Android Studio ที่ทางทีมพัฒนาได้เพิ่มเข้าในตั้งแต่เวอร์ชัน 2.0 เป็นต้นไป ซึ่งบอกเลยว่าฟีเจอร์นี้จะเข้ามาเปลี่ยนชีวิตของ Android Dev อย่างมากโขเลยล่ะ!
เพราะสิ่งแรกที่จะมาเปลี่ยนชีวิตของ Android Dev ก็คือ “เข้าไปปิดมันทิ้งซะ!!”
กำเนิด Instant Run
ถึงแม้ว่า Android Dev ส่วนใหญ่จะรู้จักกัน แต่ก็ใช่ว่าทุกๆคนนั้นจะเข้าใจเกี่ยวกับ Instant Run อย่างลึกซึ้ง ดังนั้นเจ้าของบล็อกก็คงต้องขอเกริ่นอธิบายเกี่ยวกับ Instant Run ให้ผู้ที่หลงเข้ามาอ่านรู้จักกันก่อนเนอะ ส่วนผู้ที่หลงเข้าอ่านคนไหนที่รู้จักอยู่แล้วก็สามารถข้ามไปได้เลยจ้า หรือจะอ่านเพื่อเก็บรายละเอียดปลีกย่อยก็ได้เช่นกัน
Android Studio เป็น IDE ที่ค่อนข้างฉลาดมาก+เทพครับ เมื่อเทียบกับ IDE หลายๆตัวที่เจ้าของบล็อกเคยใช้มา ซึ่งเบื้องหลังความเทพของมันก็คือ IntelliJ IDEA นี่แหละ (ต้องกราบขอบพระคุณงามๆ ที่เปลี่ยนจาก Eclipse มาเป็น IntelliJ IDEA)
แต่ถึงแม้จะมีความฉลาดและเทพสูงมากก็ตาม แต่อะไรที่ฉลาดมากก็หมายความว่ามันต้องคิดให้เราล่วงหน้าไว้เยอะ ช่วยคำนวณแทนเราไว้เยอะ เพราะงั้นเป็นเรื่องปกติที่ Android Studio จะกลายเป็นหนึ่งใน IDE ที่โคตรกินสเปคคอมพิวเตอร์ ซึ่งส่วนใหญ่ก็มาจาก Gradle เนี่ยแหละ
เจ้าของบล็อกเชื่อว่าความน่ารำคาญระหว่างการเขียนโค้ดของ Android Dev ส่วนใหญ่จะอยู่ที่ตอน Gradle ทำงาน ดังนั้นใครที่รู้สึกว่า Gradle ทำงานช้ามากบนเครื่องตัวเอง โปรดอย่าแปลกใจครับ อย่างน้อยก็ไม่ใช่แค่ผู้ที่หลงเข้ามาอ่านคนเดียวหรอกน่ะ เพราะ Gradle จะทำขั้นตอนทั้งหมดใหม่ทุกครั้งที่แก้ไขโค้ดแล้วอยากจะเห็นการทำงานว่าเป็นไปตามที่ต้องการหรือป่าว
ซึ่งทาง Android Studio ก็ไม่ได้นิ่งนอนใจครับ (เจ้าของบล็อกเชื่อว่าคนในทีมพัฒนา Android Studio ก็คงเบื่อปัญหานี้เหมือนกันแหละ) จึงได้พัฒนาสิ่งที่เรียกว่า Instant Run เพิ่มเข้ามา และเริ่มให้ใช้งานตั้งแต่ Android Studio 2.0 เป็นต้นมา
ปกติแล้วเวลา Dev เขียนโค้ดเสร็จก็มักจะกดปุ่ม Run เพื่อรันแอปฯบน Emulator หรือเครื่องจริงๆใช่มั้ยล่ะครับ ซึ่ง Android Studio ก็จะทำการ Compile โค้ดให้กลายเป็น APK โดยมี Gradle เป็นหัวใจสำคัญในขั้นตอนนั้น และนั่นแหละครับที่ Gradle ได้แสดงความสามารถที่แท้จริงออกมาให้เห็นเป็นประจักษ์
“Build นานชิบหาย”
“ไปชงกาแฟดีกว่า”
“จับโปเกมอนได้หลายตัวเลย”
ก็นั่นล่ะฮะ ยิ่งโปรเจคใหญ่มากเท่าไร ก็ยิ่ง Build นานเท่านั้น (เจ้าของบล็อกเคยเจอโปรเจคใหญ่ขนาด Build นาน 6 นาที)
เนื่องจากปัญหาคือกด Run หนึ่งครั้ง มันก็จะไป Build โปรเจคให้กลายเป็น APK ทุกครั้ง
แต่…จะดีกว่ามั้ยถ้า Dev สามารถอัปเดตโค้ดได้โดยที่ไม่ต้อง Build ใหม่
นั่นล่ะครับคือจุดเริ่มต้นของ Instant Run บน Android Studio
Instant Run คืออะไร?
เป็นฟีเจอร์ของ Android Studio ที่จะช่วยให้ Dev แก้ไขโค้ดแล้วอัปเดตบนเครื่องโดยไม่ต้อง Compile ใหม่ นั่นหมายความว่ามันจะกระโดดข้ามผ่านขั้นตอนหลายๆอย่างของ Gradle ที่ทำให้เสียเวลา Compile นานนั่นเอง
หลักการของ Instant Run คือ เมื่อ Dev เปิดใช้งาน Instant Run บน Android Studio ในครั้งแรกที่ Gradle ทำการ Build ก็จะใช้เวลานานเหมือนเดิมแหละ แต่เจ้าตัว Android Studio จะแอบปรับเปลี่ยนโค้ดเล็กน้อย เพื่อให้ตัวแอปฯเชื่อมต่อกับ Android Studio อยู่ตลอดเวลาที่มันทำงาน (นั่นหมายความว่า Instant Run จะหยุดทำงานถ้า Emulator หรืออุปกรณ์แอนดรอยด์ถูกถอดออก) จากนั้นเมื่อมีการแก้ไขโค้ดก็จะส่งชุดโค้ดที่มีการเปลี่ยนแปลงไปแทนที่ของเก่าบนอุปกรณ์แอนดรอยด์ทันที เย้!
จะเห็นว่า Instant Run ทำให้ชีวิตของ Dev ทันใจมากขึ้นในระดับวินาทีเลยล่ะ!!
การทำงานแบบเบื้องลึก
เบื้องหลังความสามารถนี้คือ Android Studio แอบไปปรับเปลี่ยนโค้ดในแอปฯให้สามารถทำงานเป็น App Server ได้ และให้เชื่อมต่อกับ Android Studio อยู่ตลอดเวลา เพื่อที่จะได้อัปเดตโค้ดเฉพาะบางส่วนได้โดยไม่ต้องไป Compile ใหม่
อาจจะฟังดูเหมือนง่าย แต่ก็มีเรื่องจุกจิกมากมายที่เกิดขึ้นอยู่เบื้องหลังนี้ ก่อนอื่นมาดูรูปนี้กันก่อน
ภาพข้างบนนี้เป็นรูปขั้นตอนการทำงานโดยปกติของ Android Studio เมื่อ Compile โค้ดให้กลายเป็น APK
- Manifest หรือ ที่รู้จักกันในชื่อของ Android Manifest จะถูกรวม (Merge) เข้าด้วยกัน (เพราะไลบรารีทุกตัวมี Manifest ของตัวเอง ดังนั้นในหนึ่งโปรเจคก็จะมี Manifest หลายไฟล์) เมื่อรวมเสร็จแล้วก็จะส่งต่อไปให้ AAPT
- ซึ่งเจ้า AAPT หรือชื่อเต็มๆคือ Android Asset Packaging Tool ที่ทำหน้าที่จัดการกับ Resource ทั้งหมดของแอนดรอยด์ ก็จะไปรวมไฟล์ Resource ทั้งหมด (พวก XML ในโปรเจคก็คือ Resource นั่นเอง รวมไปถึง Android Manifest ที่ Merge เสร็จแล้วด้วย) เพื่อเอาไปเก็บไว้ใน APK
- ฝั่ง Java ก็จะถูก javac ทำการ Compile โค้ด Java ให้กลายเป็น
.class
จากนั้นก็จะถูกทำให้กลายเป็นไฟล์.dex
อีกทีแล้วเก็บไว้ใน APK
แต่พอมีการใช้ Instant Run เพิ่มเข้ามา APK ที่ได้จากการ Build โดยมี Instant Run อยู่ด้วย ก็จะมีการเพิ่มโค้ดบางอย่างเพื่อให้สามารถอัปเดตโค้ดแบบทันทีได้
เมื่อดูจากภาพข้างบน (และไม่รู้สึกว่ามันงง) ก็จะเห็นว่าการทำงานของ Instant Run จะเข้าไปแทรกขั้นตอนเดิมๆของการ Build APK เพื่อตรงจุดที่แทรกนี่แหละจะไปปรับเปลี่ยนเล็กน้อยเพื่อให้ได้ไฟล์ APK ที่สามารถอัปเดตโค้ดได้โดยไม่ต้อง Compile ใหม่
Instant Run จะถูกแทรกเข้าไปใน Android Manifest (เพราะมันต้องแทรกโค้ดใน Android Manifest เพื่อให้ทำงานเป็น App Server ได้)
และ Instant Run จะแทรกเข้าไปใน .class
ที่ถูก Compile ด้วย javac แล้วส่งให้ dex ต่อ ในขณะเดียวกันก็จะมีการแทรกไฟล์ Application และ App Server ของ Instant Run เพิ่มเข้าไปอีกด้วย
นั่นหมายความว่า Android Manifest กับ .dex
ที่อยู่ใน APK มีการติดตั้งโค้ดของ Instant Run แล้วนั่นเอง
และตัวโค้ดในโปรเจคทั้งหมดจะถูกแบ่งออกเป็นหลายๆชุดด้วยกัน (เห็นเค้าว่า 11–12 ชุด) และแต่ละชุดจะมี .dex เป็นของตัวเอง ซึ่งแต่ละชุดจะแยกจากกัน เป็นคนละ Package เพื่อที่ว่าเวลามีการแก้ไขโค้ดใดๆก็ตามก็จะสามารถอัปเดตเฉพาะบางชุดได้ ซึ่ง Gradle ก็จะคอยเช็คในส่วนนี้ให้ว่าโค้ดส่วนไหนมีการเปลี่ยนแปลง
การใช้งาน Instant Run
ใน Android Studio เวอร์ชันหลังๆส่วนใหญ่จะเปิด Instant Run ให้ตั้งแต่แรกอยู่แล้วนะ แต่ก็จะบังคับว่าให้อัปเดต Gradle Plugin ตามด้วย แต่ถ้าของผู้ที่หลงเข้ามาอ่านคนใดไม่ได้เปิดใช้งานอยู่ก็ลองเข้าไปดูวิธีเปิดใช้งานได้ที Android Studio 2.0 :: ทำความรู้จักกับ Instant Run เร็วฟ้าผ่ากัน
ใช้งานได้หรือไม่ ให้สังเกตที่ปุ่ม Run ครับ เพราะมันจะมีสัญลักษณ์สายฟ้าสีเหลืองๆอยู่ด้วย ซึ่งในการ Build ครั้งแรก (เรียกกันว่า Full Buid) จะยังไม่มีสัญลักษณ์นี้ แต่เมื่อ Build เสร็จและแอปฯก็ถูกติดตั้งลงในอุปกรณ์แอนดรอยด์แล้ว ก็จะเห็นสัญลักษณ์นี้เพิ่มเข้ามาแทนครับ
แต่ในกรณีทีเปิด Instant Run ให้กับโปรเจคแล้วไม่มีสัญลักษณ์ดังกล่าว ให้ลองเช็คว่า Gradle Plugin อัปเดตเป็นเวอร์ชันล่าสุดแล้วหรือยัง
แต่สุดท้ายก็ปิด Instant Run อยู่ดี…
ถึงแม้ว่า Instant Run จะทำให้สามารถอัปเดตโค้ดได้ทันทีโดยไม่ต้อง Compile ใหม่ แต่ Dev ส่วนใหญ่ก็เจอปัญหาเวลาแก้ไขโค้ดแล้วโค้ดไม่ส่งผลบ้าง หรืออัปเดต Resource แล้วไม่เปลี่ยนแปลงบ้าง ทั้งนี้ก็เพราะว่าตัว Instant Run ยังไม่ได้สมบูรณ์โดยแท้ แต่จะมีการอัปเดตปรับปรุงอยู่ตลอดเวลาใน Android Studio เวอร์ชันใหม่ๆ
แต่ทว่าก็ยังส่วนหนึ่งที่เจ้าของบล็อกพบก็คือ Instant Run ทำงานถูกต้องแล้ว แต่ Dev ไม่ได้เข้าใจการทำงานของ Instant Run จึงทำให้เข้าใจผิดว่า Instant Run ทำงานไม่ถูกต้อง
ถ้ายังอยากปิด Instant Run จริงๆ ก็สามารถเข้าไปปิดใน Preference ของ Android Studio ได้เลย
รู้จักกับ 3 รูปแบบการทำงานของ Instant Run
อาจจะฟังดูเหมือนว่า Instant Run จัดการให้หมดแล้ว แต่จริงๆแล้วผู้ที่หลงเข้ามาอ่านควรทำความเข้าใจกับรูปแบบการทำงานของ Instant Run ก่อน เพราะเวลาที่มันทำงานในแต่ละรูปแบบจะมีผลลัพธ์ที่ต่างกันนั่นเอง ซึ่งมีดังนี้
- Hot Swap
- Warm Swap
- Cold Swap
Hot Swap รวดเร็วทันใจ
เป็นการเปลี่ยนโค้ดในฉับพลันเลย ซึ่งเป็นรูปแบบที่ Instant Run ทำงานได้ไวที่สุดแล้ว โดยจะทำงานเมื่อมีการแก้ไขโค้ดที่มีอยู่แล้วใน Method แต่ละตัว (พวกคำสั่งเล็กๆน้อยๆนั่นแหละ) โดย Instant Run จะส่งโค้ดตัวนั้นๆเข้าไปทันที และทำการ Override คำสั่งเก่าๆซะเพื่อให้เรียกมาที่คำสั่งอัปเดตใหม่
หรือก็คือ APK ยังคงเป็นตัวเก่าอยู่ แต่โค้ดใหม่ถูกส่งเพิ่มเข้ามา แล้วทำการ Override แทนที่ Class เก่าเลย
ซึ่งการทำงานรูปแบบนี้จะช่วยอำนวยความสะดวกกับ Dev มากๆในเวลาที่แก้ไขโค้ดเล็กๆน้อยๆเท่านั้น เพราะมันใช้เวลาไวมาก (ขึ้นอยู่กับว่าแก้ไขโค้ดมากน้อยแค่ไหนด้วย) และส่วนใหญ่ใช้เวลาไม่ค่อยเกิน 10 วินาทีด้วยซ้ำ!!
เงื่อนไข
- แก้ไขโค้ดที่เดิมมีอยู่แล้ว โดยไม่ส่งผลกับโค้ดโดยรวมมากนัก
ผลลัพธ์จากการทำงาน
- โค้ดเปลี่ยนแปลงทันทีโดยไม่ส่งผลอะไรกับแอปฯที่ทำงานอยู่
- โค้ดจะมีผลเมื่อเรียกใช้งานคำสั่งนั้นๆในครั้งต่อไป
- Activity ยังคงทำงานอยู่เหมือนเดิม ไม่มีการถูกทำลายเพื่อสร้างขึ้นมาใหม่
Warm Swap ไม่เร็วมากนัก แต่ก็ยังถือว่าเร็วอยู่ดี
เมื่อมีการแก้ไขเกี่ยวกับ Resource จะไม่สามารถทำ Hot Swap ได้ เพราะ Resource มันจะต้องมีการ Repack ใหม่แล้วอัปเดตให้กับตัวแอปฯ ดังนั้นเวลาที่มีการแก้ไขหรือลบ หรือเปลี่ยนแปลงอะไรใน Resource ก็จะทำให้เกิด Warm Swap นั่นเอง
เงื่อนไข
- แก้ไขหรือลบ Resource ใดๆก็ตาม เช่น แก้ไขข้อความใน String XML หรือลบ Value XML บางตัวออกไป หรือจัดย้ายตำแหน่งของ View ใน Layout XML ใหม่
ผลลัพธ์จากการทำงาน
- Resource จะมีการอัปเดตใหม่ โดยที่ไม่ต้องติดตั้งแอปใหม่
- Activity จะถูก Recreate ใหม่เพื่ออัปเดต Resource
Cold Swap แบบช้าๆ แต่ก็ดีกว่า Full Build
เป็นรูปแบบการทำงานเฉพาะบน API 21 ขึ้นไปเท่านั้น เวอร์ชันที่ต่ำกว่านั้นจะกลับไปเป็น Full Build ทั้งหมด ซึ่ง Cold Swap จะเกิดขึ้นก็ต่อเมื่อมีการแก้ไขโค้ดที่ส่งผลต่อ Structure ที่ไม่สามารถทำ Hot Swap ได้แล้ว (เพราะโค้ดไม่ได้มีการเปลี่ยนแปลงเฉพาะบางจุดที่สามารถ Override ทับได้) หรือแก้ไข Resource ที่ต้อง Reindex ใหม่
เนื่องจากโค้ดของ Dev จะถูกแบ่งออกเป็นหลายๆชุด ซึ่ง Cold Swap นี่แหละที่จะไป Compile และอัปเดตโค้ดของชุดที่มีการเปลี่ยนแปลงเท่านั้น ทำให้โค้ดที่อยู่คนละชุดไม่ต้องเสียเวลา Compile ใหม่
เงื่อนไข
- ทำงานเฉพาะบน API 21 ขึ้นไปเท่านั้น เวอร์ชันที่ต่ำกว่าจะกลายเป็น Full Build แทน
- มีการเพิ่ม/ลบ/แก้ไขโค้ดที่ส่งผลต่อ Structure ของโปรแกรม (Instance Field, Instance Method, Static Field, Static Method, Static Class Initializer, Parent Class ของ Class, Interface)
- มีการแก้ไขหรือเพิ่ม Resource ตัวใหม่เข้ามาที่ส่งผลให้ AAPT ต้อง Reindex เพื่อสร้าง ID ของ Resource แต่ละตัวใหม่
ผลลัพธ์จากการทำงาน
- แอปฯจะถูกปิดลงแล้วเปิดขึ้นมาใหม่
- ก็ต้องติดตั้ง APK ใหม่อยู่ดี แต่ลดเวลาตอน Build มากกว่า Full Build
แต่การแก้ไข Android Manifest ก็ต้อง Full Build อยู่ดี
ถึงแม้ว่า Instant Run จะช่วยหลายๆการกระทำให้สะดวกขึ้น แต่เมื่อแก้ไข Android Manifest ก็ยังต้องต้องทำ Full Build ทุกครั้ง เนื่องจาก Android Manifest เป็นไฟล์ที่อุปกรณ์แอนดรอยด์จะเปิดอ่านข้อมูลเฉพาะครั้งแรกตอนที่ติดตั้ง APK เท่านั้น ดังนั้นจึงเลี่ยงไม่ได้ที่จะต้องทำ Full Build เพื่อเข้าขั้นตอนติดตั้ง APK ใหม่
ข้อจำกัดบางอย่าง
ถึงแม้ว่า Instant Run จะดีงามก็จริง แต่ก็ยังมีบางอย่างที่เป็นข้อจำกัดอยู่เหมือนกัน อย่างเช่น ไม่สามารถใช้ร่วมกับ Jack Compiler ไม่สามารถใช้กับ Instrumentation Test และไม่สามารถ Deploy บนอุปกรณ์แอนดรอยด์หลายๆเครื่องพร้อมๆกันได้
และก็ยังมีบั๊กเวลาแก้ไข View แล้วเกิดอาการเพี้ยนๆเป็นบางครั้ง (แก้ไขด้วยการ Run > Clean and Rerun)
สิ่งที่นักพัฒนามักจะเข้าใจผิด
เจ้าของบล็อกเชื่อว่าผู้ที่หลงเข้ามาอ่านส่วนใหญ่น่าจะเจออะไรคล้ายๆกันเวลาใช้ Instant Run โดยเฉพาะเวลาที่ใช้งานแล้วรู้สึกว่า Instant Run ทำให้แอปฯแสดงผลเพี้ยนๆบ้าง ไม่อัปเดตค่าบ้าง สุดท้ายก็ต้องมานั่ง Clean Project ใหม่ทุกครั้งเพื่อให้มันทำงานได้เหมือนเดิม
กดต้องมานั่งกด Clean Project บ่อยๆ แล้ว Instant Run มันจะมาช่วยให้เร็วขึ้นได้ยังไงล่ะเนอะ? เพราะงั้นก็ปิด Instant Run แม่มซะเลย
แต่ทีนี้เจ้าของบล็อกอยากให้มาดูก่อนว่า จริงๆแล้วไอ้ปัญหาที่เจอกันระหว่างใช้งาน Instant Run เกิดมาจากความเข้าใจผิดหรือป่าว หรือโค้ดทำงานไม่ถูกต้องตั้งแต่แรกแล้วหรือป่าวนะ?
Instant Run กดเมื่อไรก็อัปเดตในทันที
ที่เจอกันได้ค่อนข้างบ่อยคือ Concept ของ Instant Run คือแก้ไขแล้วเปลี่ยนแปลงเห็นผลในไม่กี่วินาที จึงทำให้นักพัฒนาส่วนใหญ่เข้าใจว่าถ้าแก้ไขบางอย่างแล้วจะต้องอัพเดทให้เห็นผลคำสั่งนั้นๆทันทีในทุกครั้ง
ยกตัวอย่างเช่น เจ้าของบล็อกมีคำสั่งของ Activity แบบง่ายๆอยู่ตัวหนึ่ง
public class VeryAwesomeActivity extends Activity {
private static final String TAG = VeryAwesomeActivity.class.getName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_very_awesome);
Log.e(TAG, "Hello World");
}
}
ถ้าดูจากโค้ดคร่าวๆก็จะเห็นว่า เป็น Activity ที่จะแสดงคำว่า Hello World ใน Logcat เมื่อตอนที่ Activity ตัวนี้ถูกสร้างขึ้น
แล้วเกิดเจ้าของบล็อกเปลี่ยนใจอยากใช้ Toast แทนล่ะ
public class VeryAwesomeActivity extends Activity {
private static final String TAG = VeryAwesomeActivity.class.getName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_very_awesome);
Toast.makeText(this, "Hello World", Toast.LENGTH_SHORT).show();
}
}
พอกด Run ด้วย Instant Run ปุ๊ป สิ่งที่เกิดขึ้นคือข้อความควรเปลี่ยนจากใน Logcat มาแสดงเป็น Toast ใช่มั้ยล่ะครับ
สิ่งที่เกิดขึ้นคือ ไม่มีอะไรเกิดขึ้นเลย Toast ไม่มีการแสดงข้อมูลเลย ทั้งๆที่มีการเปลี่ยนคำสั่งในโค้ดไปแล้ว หรือว่านี่คือบั๊กของ Instant Run กันนะ?
ซึ่งจริงๆแล้ว Instant Run ทำงานถูกต้องแล้วครับ แต่ Dev ต่างหากที่ไม่เข้าใจการทำงานของ Instant Run เพราะสิ่งที่เกิดขึ้นในตัวอย่างนี้คือ Hot Swap ซึ่ง Hot Swap จะอัปเดตโค้ดใหม่เข้าไปแล้ว Override แทนที่ของเก่าทันที โดยที่ Activity ยังคงทำงานอยู่เหมือนเดิม ไม่มีการ Restart Activity
เมื่อ Hot Swap ไม่มีการ Restart Activity แล้ว onCreate จะทำงานใหม่อีกครั้งหรือป่าว?
นั่นล่ะครับคือสิ่งที่เกิดขึ้น เพราะ Hot Swap ไม่ทำให้ Activity ถูก Restart ก็เลยทำให้ onCreate ไม่ถูกเรียกใช้งานซ้ำนั่นเอง จึงเป็นสาเหตุว่าแก้ไขโค้ดที่ผูกไว้กับ onCreate แล้วไม่เกิดการเปลี่ยนแปลงเมื่อใช้ Instant Run
เพราะงั้นถ้าผู้ที่หลงเข้ามาอ่านเคยเจอปัญหาคล้ายๆกันแบบนี้ ลองเช็คใหม่ดูครับว่าจริงๆแล้วเป็นเพราะ Hot Swap มันไม่ Restart Activity หรือป่าว?
จนล่าสุดทางทีม Android Studio จึงต้องใส่ปุ่มตั้งค่าเพิ่มมาอีกหนึ่งปุ่ม นั่นก็คือบังคับให้ Activity ทำการ Restart ใหม่ทุกครั้งไปเลย
เพราะงั้นแนะนำให้เข้าไปกดเปิดละกันครับ…
เกิดอะไรกับตอน Warm Swap
เวลาที่เกิด Warm Swap (หรือสั่งให้ Activity Restart ทุกครั้ง) สิ่งที่เกิดขึ้นคือ Activity ถูกทำลายลง และในระหว่างที่ถูกทำลายก็จะเก็บค่าต่างๆไว้ และเมื่อเริ่มทำงานใหม่อีกครั้งก็จะคืนค่าที่เก็บไว้กลับมา
Save/Restore Instance State นั่นเอง!!
เพื่อที่ว่าแอปฯจะได้ทำงานต่อเนื่องจากของเดิมได้ทันทีที่เกิด Warm Swap ซึ่งคำตอบที่เจ้าของบล็อกอยากจะถามก็คือ
แล้วแอปฯของผู้ที่หลงเข้ามาอ่านจัดการกับ Instance State เหล่านั้นอย่างถูกต้องแล้วหรือยัง?
ถ้าผู้ที่หลงเข้ามาอ่านยังไม่ได้ทำอะไรเลย สิ่งที่เกิดขึ้นคือเมื่อเกิด Warm Swap เมื่อไร ก็จะทำให้ Instance ทุกตัวถูกเคลียร์ทิ้งไปเลย ในขณะที่ View ต่างๆของแอนดรอยด์ยังคงสามารถจัดการเรื่องนี้ให้อยู่
ดังนั้นหัวใจสำคัญคือ แอปฯควรจัดการกับ Instance State ด้วยเพื่อที่จะได้ Warm Swap
ถ้าผู้ที่หลงเข้ามาอ่านคนใดไม่รู้จัก จงเข้าไปอ่านกันที่ มา Save/Restore กับ Instance State บน Activity ให้ถูกต้องกันเถอะ
สรุป
Instant Run เป็นฟีเจอร์หนึ่งใน Android Studio ที่จะเข้ามาช่วยเปลี่ยนชีวิตของ Dev ให้ดียิ่งขึ้น ลดระยะเวลาในการ Build ลงซึ่งเป็นหนึ่งในสาเหตุหลักที่ทำให้สิ้นเปลืองเวลาในการพัฒนาโปรเจคซักตัว แต่ถึงกระนั้น Instant Run ก็มีเบื้องหลังที่ค่อนข้างซับซ้อนพอสมควรที่ Dev จะต้องทำความเข้าใจกับการทำงานของมันเสียก่อนถึงจะใช้งานได้ดี แต่ในความเป็นจริงก็มี Dev บางส่วนที่ยังไม่รู้ว่ามีความสามารถนี้ด้วยซ้ำ ฮาๆ พอไม่เข้าใจการทำงานของมัน เวลาใช้งานแล้วพบปัญหาก็ไม่รู้ว่าเป็นเพราะอะไร จึงทำให้ส่วนใหญ่เลือกที่จะปิดใช้งานไป หรือบ้างก็ไม่รู้จักก็เลยต้องใช้วิธี Clean Project ใหม่ทุกครั้ง
เจ้าของบล็อกก็คงแนะนำว่าอยากให้ Android Dev ควรจะต้องรู้จักกับ Instant Run แล้วล่ะ เพราะมันติดมากับ Android Studio ตั้งแต่แรก ถ้าไม่ได้ใช้งานมัน ก็จะไปเข้าลูปเดิมๆของการ Build Gradle ที่ทำให้สิ้นเปลืองเวลา แต่ถ้าใช้งานมันก็ควรจะต้องทำความเข้าใจการทำงานของมันก่อน เพื่อให้สามารถใช้ได้อย่างไม่มีปัญหา เพราะปัญหาหลักๆที่ส่วนใหญ่เจอกันก็คือ ไม่เข้าใจการทำงานของ Hot Swap และไม่ได้จัดการกับ Instance State ให้ถูกต้องตั้งแต่แรกอยู่แล้ว
ซึ่งจากการลองใช้งานจริงๆ เจ้าของบล็อกก็พบว่า Instant Run มันตอบโจทย์การทำงานได้ค่อนข้างดีครับ เจ้าของบล็อกสามารถเขียนโค้ดแล้วรับ Feedback ได้ไวขึ้น ทำให้ย่นระยะเวลาในการทำงานไปได้พอสมควร แต่การทำงานของ Instant Run ก็อาจจะยังไม่สมบูรณ์ 100% โดยเฉพาะกับโปรเจคใหญ่มากๆ ซึ่งอันนั้นก็ต้องยอมปิดใช้งานไป แต่สำหรับโปรเจคทั่วไปแล้วเจ้าของบล็อกก็แนะนำให้ลองใช้งานดูครับ