5 เทคนิค Debug ขั้นเทพใน Android Studio

เพราะชีวิตคือการ debug

Travis P
Black Lens

--

การ 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 นั้น มันก็จะหยุดเฉพาะครั้งที่ตรงเงื่อนไข

  1. แปะ breakpoint ธรรมดาๆ
  2. คลิกขวาที่ breakpoint จะมี dialog ขึ้นมาให้ใส่ condition ตามต้องการ
  3. debug ตามปกติ และพบว่ามันหยุดตามเงื่อนไขได้อย่างน่าอัศจรรย์ใจ
แปะ breakpint ตามปกติ
คลิกขวา ใส่เงื่อนไข
หยุดเฉพาะที่ตรงเงื่อนไข

Exception Breakpoint

เวลาแอพแครชนี่ stack trace ถือเป็นเพื่อนรักเราเลยนะครับ บอกเราว่าต้นตอมาจากไหน แต่บางทีมันก็ทรยศเรา พ่นอะไรออกมาก็ไม่รู้ ไม่เห็นจะตรงบรรทัดเลย แล้วก็ทำให้เราต้องไปไล่แปะ breakpoint ไปเรื่อยๆจนกว่าจะเจอต้นตอ

พอแล้วครับ เหนื่อย ต่อไปนี้ผมไม่ไล่แปะตามบรรทัดละ ผมจะฝาก Android Studio ให้ break ณ บรรทัดที่เกิด exception ขึ้นทันทีด้วยฟีเจอร์ Exception Breakpoint ดังนี้

  1. Run > View Breakpoints หรือ cmd + shift + F8
  2. กด + เลือก Java Exception Breakpoints
  3. เลือก/search Exception ที่ต้องการ
  4. เช็คให้แน่ใจว่า exception ที่เราสนใจมันติ๊กถูกอยู่
  5. debug ตามปกติ จนมันติด breakpoint เองได้อย่างทันท่วงที
cmd + shift + F8 จากนั้นกด +
เอา Java Exception Breakpoints
เลือก Exception ที่ต้องการ
ถ้าไม่ตั้งค่าอื่นๆก็ Done ได้เลย
ต๊ะเอ๋

สุดท้ายก็มาติด 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 แล้วรันใหม่

บ่อยครั้งที่เรางงๆกับค่าอะไรสักอย่าง เรามักจะจับมัน log ออกมาดูใช่มั้ยครับ ยกตัวอย่างเช่นอยากดู header ของ response ก็ต้องไปเติมโค้ด log แล้วรันใหม่อีก

Evaluate Expression ช่วยได้ครับ จังหวะที่เราติด breakpoint อยู่ เราสามารถเขียนโค้ด แล้วรันได้ ณ ขณะนั้นเลย (คล้ายๆกับ JavaScript console ใน chrome)

  1. เริ่มจากเล่นแอพให้ติด breakpoint ณ ตำแหน่งที่สนใจก่อน
  2. กดปุ่ม Evaluate Expression หรือ opt + F8
  3. อยากรู้อะไรก็พิมพ์ๆไป Evaluate แล้วดู result
  4. ถ้าบรรทัดเดียวไม่สะใจก็กด Code Fragment Mode แล้วพิมพ์ได้เต็มที่ (result ได้มาจากบรรทัดสุดท้าย)
  5. ถ้าเรา println() มันจะไปโผล่ใน debugger console
opt + F8 หรือกดตรงนี้
ใส่ expression แล้วได้ค่ามากมาย กดดูได้เหมือน debug ปกติ
ใน Code Fragment Mode สามารถรัน snippet ได้เลย
println() ทั้งหลายมาออกใน debug console ตรงนี้

ครบ 5 อันแล้วครับ เอาไว้มีอะไรใหม่จะมาเล่าอีก 🖖

ปรมมือสิครับ รออะไรอยู่

--

--

Travis P
Black Lens

Android Developer, Kotlin & Flutter Enthusiast and Gamer