5 เทคนิค Debug ขั้นเทพใน Android Studio
เพราะชีวิตคือการ debug
การ debug นี่ถือเป็น survival skill สำหรับ developer อย่างเราๆเลยนะครับ จากประสบการณ์ตรงแล้ว ก็มีบ้างแหละที่ debug ยาก บางที Exception มาจากตรงไหนไม่รู้ stack trace ก็ไม่ช่วยอะไร บางทีเราก็สงสัยว่าทำไม method นี้คืนค่าไม่เหมือนที่เราคิดไว้ ใครเป็นคนเรียก method นี้ โอ้ยงง
ถ้าคุณก็เป็นคนหนึ่งที่ประสบปัญหาเหล่านี้ ผมหวังว่าโพสนี้จะช่วยคุณได้
Attach Debugger
รู้หมือไร่ คุณสามารถ debug app ที่รันอยู่แล้วได้โดยไม่ต้อง build install ใหม่ ด้วยการกดปุ่ม Attach debugger to Android process หรือที่บางคนเรียกว่า แปะแมง นั่นเอง
Conditional Breakpoint
เคยมั้ยครับ เวลาที่มี loop เราตั้งใจจะหยุดตอน item ที่ 5 แล้วมันก็ break ตั้งแต่ item ที่ 0 ทำให้เราต้องนั่งกดปล่อยถึง 5 ครั้งด้วยกัน เสียเวลาเป็นอย่างมาก
Conditional Breakpoint ช่วยพวกเราได้ เพียงแค่เราใส่เงื่อนไขเพิ่มให้กับ breakpoint นั้น มันก็จะหยุดเฉพาะครั้งที่ตรงเงื่อนไข
- แปะ breakpoint ธรรมดาๆ
- คลิกขวาที่ breakpoint จะมี dialog ขึ้นมาให้ใส่ condition ตามต้องการ
- debug ตามปกติ และพบว่ามันหยุดตามเงื่อนไขได้อย่างน่าอัศจรรย์ใจ
Exception Breakpoint
เวลาแอพแครชนี่ stack trace ถือเป็นเพื่อนรักเราเลยนะครับ บอกเราว่าต้นตอมาจากไหน แต่บางทีมันก็ทรยศเรา พ่นอะไรออกมาก็ไม่รู้ ไม่เห็นจะตรงบรรทัดเลย แล้วก็ทำให้เราต้องไปไล่แปะ breakpoint ไปเรื่อยๆจนกว่าจะเจอต้นตอ
พอแล้วครับ เหนื่อย ต่อไปนี้ผมไม่ไล่แปะตามบรรทัดละ ผมจะฝาก Android Studio ให้ break ณ บรรทัดที่เกิด exception ขึ้นทันทีด้วยฟีเจอร์ Exception Breakpoint ดังนี้
- Run > View Breakpoints หรือ
cmd + shift + F8
- กด + เลือก Java Exception Breakpoints
- เลือก/search Exception ที่ต้องการ
- เช็คให้แน่ใจว่า exception ที่เราสนใจมันติ๊กถูกอยู่
- debug ตามปกติ จนมันติด breakpoint เองได้อย่างทันท่วงที
สุดท้ายก็มาติด UnsuportedOperationException
ที่ผมแอบ throw
ไว้เอง สาบานได้ว่าไม่ได้แปะ breakpoint ไว้จริงๆ
Call Stack
เพื่อนๆจำคำว่า spaghetti code ได้มั้ยครับ มันคืออาการที่โค้ดพันกันจนเราไม่รู้ว่าโค้ดบรรทัดนี้ถูกรันได้ไง ใครเป็นคนเรียก ผมว่าไม่มีใครอยากให้โค้ดมันยุ่งหรอก แต่ถ้ามันยุ่งไปแล้ว ผมหวังว่าเทคนิคนี้จะช่วยได้
Call stack เป็นคำที่ผมไม่มั่นใจว่าเรียกถูกหรือเปล่า แต่ผมให้นิยามว่ามันคือลำดับการเรียก function จนถึงปัจจุบัน สามารถดูได้ที่ tab Frames ใต้ debugger
ยกตัวอย่างเช่น ปัจจุบันผม break อยู่ที่ setUpRecyclerView()
ซึ่งถูกเรียกในsetUpWidgets()
ซึ่งถูกเรียกใน onCreate()
อีกที
เราสามารถขยับไปดู ณ function ต่างๆใน call stack ได้ สมมติผมดู onCreate()
ก็ยังเห็นค่าตัวแปรใน scope นั้นอีกด้วย
แน่นอนว่า call stack มันย้อนกลับไปถึง main()
ได้เลยทีเดียว ตรงนี้สังเกตว่าใน stack ที่ highlight สีเหลืองคือไม่ได้อยู่ใน source code ของเรา
Evaluate Expression
บ่อยครั้งที่เรางงๆกับค่าอะไรสักอย่าง เรามักจะจับมัน log ออกมาดูใช่มั้ยครับ ยกตัวอย่างเช่นอยากดู header ของ response ก็ต้องไปเติมโค้ด log แล้วรันใหม่อีก
Evaluate Expression ช่วยได้ครับ จังหวะที่เราติด breakpoint อยู่ เราสามารถเขียนโค้ด แล้วรันได้ ณ ขณะนั้นเลย (คล้ายๆกับ JavaScript console ใน chrome)
- เริ่มจากเล่นแอพให้ติด breakpoint ณ ตำแหน่งที่สนใจก่อน
- กดปุ่ม Evaluate Expression หรือ
opt + F8
- อยากรู้อะไรก็พิมพ์ๆไป Evaluate แล้วดู
result
- ถ้าบรรทัดเดียวไม่สะใจก็กด Code Fragment Mode แล้วพิมพ์ได้เต็มที่ (
result
ได้มาจากบรรทัดสุดท้าย) - ถ้าเรา
println()
มันจะไปโผล่ใน debugger console
ครบ 5 อันแล้วครับ เอาไว้มีอะไรใหม่จะมาเล่าอีก 🖖