02 October 2013

แอปพลิเคชันหยุดทำงาน ทำยังไงดี?

Updated on

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


        ก่อนอื่นขอให้ทำความเข้าใจเรื่องเออเรอร์กันก่อนเลยนะครับ

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

        สำหรับเออเรอร์จะแบ่งประเภทหลักๆได้สองประเภทด้วยกันคือ


Syntax Error

        เป็นการผิดพลาดที่เกิดจากการพิมโค๊ดไม่ถูกต้องตามที่กำหนด


        อันนี้เกิดมาจากการที่ผู้เขียนโปรแกรมพิมคำสั่งไม่ถูกต้องตามที่กำหนด อย่างเช่นในภาพ ประกาศตัวแปร x เป็น Integer แต่ดันกำหนดค่าด้วย String ดังนั้นจึงเกิดเออเรอร์ขึ้นเพื่อให้แก้ไขการกำหนดค่าตัวแปรให้ถูกต้อง


Runtime Error

        เป็นการผิดพลาดที่เกิดขึ้นในขณะที่แอปพลิเคชันทำงาน


        อันนี้เจอกันบ่อยมาก และผู้ที่หลงเข้ามาอ่านที่เป็นมือใหม่จะทำอะไรไม่เป็น เพราะเริ่มหัดเขียนจากตัวอย่าง แม้แต่ในห้องเรียน การที่เกิดเออเรอร์ขึ้นก็จะเข้าใจว่าพิมโค๊ดผิดหรือไม่ตรงกับตัวอย่าง แต่ในการเขียนโปรแกรมจริงๆที่ไม่ได้พึ่งตัวอย่าง จะเป็นเรื่องปกติที่ต้องเจอ ดังนั้นทางที่ดีก็ควรรู้วิธีและแนวทางในการวิเคราะห์เออเรอร์เหล่านั้น

        สำหรับ Syntax Error ไม่ขอพูดถึง เพราะมันคือพิมคำสั่งไม่ตรงกับที่กำหนด แต่จะพูดถึง Runtime Error แทน เพราะผู้ที่หลงเข้ามาอ่านมือใหม่ควรจะรู้

        เมื่อเกิด Runtime Error แอปพลิเคชันจะแจ้งข้อความประมาณนี้ทุกครั้ง


        ประมาณว่าแอปพลิเคชันดังกล่าวได้หยุดทำงานแล้ว

        เมื่อเจอแบบนี้ ทุกครั้ง ให้เริ่มทำการหาสาเหตุของเออเรอร์ก่อน ดังนี้

        1. เปิด LogCat ขึ้นมา (ต่อมือถือเข้ากับคอมเวลาทดสอบโปรแกรม) แล้วมองหาเออเรอร์ที่เกิดจากแอปพลิเคชันที่สร้างขึ้นมา จุดสังเกตง่ายๆในการดูว่าเป็นเออเรอร์จากแอปพลิเคชันที่สร้างขึ้น ให้หาข้อความสีแดงๆที่เป็นเออเรอร์ชุดใหญ่ๆ (ถ้าดูบ่อยๆจะคุ้นจนชิน) แล้วดูที่แถว Application จะเป็นชื่อ Package Name ของแอปพลิเคชันนั้นๆ




        2. ดูข้อความเออเรอที่แถวที่สองในช่อง Text นั่นล่ะคือสาเหตุ




        3. จากข้อความตัวอย่างจะแจ้งสาเหตุเออเรอดังนี้
java.lang.RuntimeException: Unable to start activity componentInfo(app.akexorcist.ioiocamerarobot/app.akexorcist.ioiocamerarobot.SplashScreen): java.lang.NullPointerException
 
        ดูคำอธิบายตามสีของตัวอักษรเลยครับ

• เป็น Runtime Error 

        คงไม่ต้องอธิบายอะไรมั้ง


• เออเรอร์เมื่อไรใน Activity นั้นๆ โดยวิเคราะห์คร่าวๆดังนี้
        Unable to start activity - ใน onCreate หรือ onStart
        Unable to resume activity - ใน onResume หรือ onRestart
        Unable to pause activity - ใน onPause
        Unable to stop activity - ใน onStop
        Unable to stop activity - ใน onDestroy

• Package Name ของแอปพลิเคชันที่เออเรอร์

• Activity ที่เออเรอ (ระบุชื่อนำหน้าด้วย Package Name)

• รูปแบบของเออเรอร์ที่เกิดขึ้น (Exception)
        จากตัวอย่างก็คือ  NullPointerException เป็นเออเรอร์จากการลืมกำหนดค่าให้กับตัวแปรหรือออบเจ็คใดๆ (ในกรณีเออเรอร์แบบอื่นอาจจะมีข้อความต่อท้ายเพิ่มเติมด้วย)


        4. ทำการหาบรรทัดของโค๊ดที่เกิดเออเรอร์ขึ้น โดยให้สังเกตบรรทัดต่อจากบรรทัดที่ 2 จะเห็นว่ามีแจ้งตำแหน่งที่เออเรอร์หลายบรรทัดมาก และจะเห็นชื่อคลาสที่ต่อท้ายด้วยว่าเออเรอร์ในคลาสอะไร ให้มองหาบรรทัดที่ต่อท้ายด้วยชื่อ Activity ที่เกิดเออเรอร์ขึ้น


        จากตัวอย่าง ในบรรทัดที่สองจะบอกว่าเกิดเออเรอร์ขึ้นที่ SplashScreen ดังนั้นก็ให้มองหาบรรทัดถัดไปที่ต่อท้ายด้วย SplashScreen.java ให้ดูตัวเลขที่ต่อท้ายชื่อคลาสนั้นๆ นั่นแหละคือบรรทัดที่เกิดเออเรอร์ จากตัวอย่างก็คือเออเรอร์ที่ SplashScreen.java ที่บรรทัด 38

        ในกรณีที่เออเรอร์เกิดมาจากคลาสย่อยที่ Activity นั้นๆเรียก ก็จะมีระบุไว้ใน LogCat ด้วย จะอยู่ใกล้ๆกันนั่นแหละครับ แต่ถ้าหาไม่เจอจริงๆให้ใช้คำสั่ง Log ไล่ดักทีละบรรทัดดูครับ [Android Dev Tips] 5 วิธีการใช้ Log และ LogCat ให้เกิดประโยชน์


        5. เมื่อรู้สาเหตุที่เออเรอร์และคำสั่งที่ทำให้เกิดเออเรอร์ ก็ให้ทำการแก้ไขข้อผิดพลาดที่เกิดขึ้นในโค๊ดนั้นๆให้ถูกต้องซะ แต่ถ้าผู้ที่หลงเข้ามาอ่านยังไม่สามารถแก้ไขโค๊ดให้ถูกต้องได้ ก็ให้ลองเอาคีย์เวิร์ดที่ได้จาก LogCat นี่แหละ ไปค้นหาใน Google โดยเอาสาเหตุที่เออเรอร์และคำสั่งที่เออเรอร์ไปค้นหา จากตัวอย่างก็จะเป็น "NullPointerException (คำสั่งที่เออเรอร์) Android"

 

        ถ้าเป็นไปได้พิมต่อท้ายว่า Stackoverflow ด้วย ก็จะเจอแน่ๆ (เป็นเว็บบอร์ดถามตอบสำหรับเหล่าโปรแกรมเมอร์ทั่วโลก)

        แต่ถ้ายังหาไม่เจอล่ะ หรือแก้ไขไม่ถูก? ลองถามผู้รู้ดูใครก็ได้ หรือเจ้าของบล็อกก็ได้ แต่สิ่งที่ควรบอกผู้ที่ปรึกษาควรประกอบไปด้วยดังนี้

        • ข้อความเออเรอร์ใน LogCat บรรทัดที่ 2 (จริงๆส่งข้อความที่เออเรอทั้งชุดมาจะดีกว่า)


        • คำสั่งที่ทำให้เกิดเออเรอร์และคำสั่งรอบข้างที่น่าจะเกี่ยวข้อง ไม่แนะนำให้ส่งโค๊ดทั้งหมดให้คนอื่นดู เพราะโค๊ดที่ซับซ้อน คนที่ปรึกษานั้นสุดท้ายก็ต้องมานั่งไล่โค๊ดอยู่ดี เพื่อทำความเข้าใจ ซึ่งจะเสียเวลากับผู้ที่ไปปรึกษา และอาจจะปวดตับตามไปด้วย ดังนั้นทางที่ดีจึงควรวิเคราะห์เบื้องต้นก่อนว่าคำสั่งไหนน่าจะเกี่ยวข้อง และบอกให้กับคนที่ปรึกษาฟังว่าโค๊ดที่เกี่ยวข้องมีประมาณนี้ๆๆ อย่าน้อยเกินไป (ดูแล้วไม่เข้าใจ) และอย่ามากจนเกินไป (ดูแล้วมึน)

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


        และสุดท้ายก่อนจบบทความ การเซฟภาพหน้าจอที่ LogCat คนที่ปรึกษาต้องการดูข้อความที่อยู่ใน Text เท่านั้น ดังนั้นเน้นภาพที่เห็นข้อความใน Text ทั้งหมดจะดีกว่า เจ้าของบล็อกเคยเจอผู้ที่หลงเข้ามาอ่านที่เซฟภาพ ในช่อง Time, PID, Application และ Tag มาให้ดู แต่ข้อความในช่อง Text ดันเซฟมาให้ดูแค่ครึ่งเดียว



        ก็จบกับบทความนี้เรียบร้อยแล้ว อยากให้ผู้ที่หลงเข้ามาอ่านที่เป็นมือใหม่ได้ลองอ่านดู แล้วฝึกที่จะวิเคราะห์เออเรอร์ก่อนที่จะถาม เพราะไม่อยากให้ติดนิสัยเอาแต่ถามอย่างเดียว อันไหนวิเคราะห์แล้วแก้ไขเองได้ก็ควรทำ อันไหนที่ไม่ได้จริงๆก็ค่อยปรึกษาผู้อื่นอีกทีหนึ่ง