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

โดยระบบปฏิบัติการณ์จะบันทึก Log สำหรับการทำงานทั้งหมดภายในเครื่องอยู่ตลอดเวลา ซึ่งรวมไปถึง Log ที่เกิดขึ้นจาก Runtime Error ด้วยเช่นกัน และนักพัฒนาก็สามารถใช้เครื่องมือบน Android Studio ที่เรียกว่า Logcat เพื่อช่วยให้อ่าน Log จากอุปกรณ์แอนดรอยด์ได้ง่ายขึ้น

นั่นจึงทำให้ Logcat นั้นเป็นเครื่องมือพื้นฐานอันดับต้น ๆ ใน Android Studio ที่นักพัฒนาควรฝึกใช้งาน เพราะจะช่วยให้นักพัฒนาวิเคราะห์ปัญหาและตรวจสอบการทำงานของโค้ดในระหว่างที่แอปกำลังทำงานอยู่

ตั้งค่าอุปกรณ์แอนดรอยด์เพื่อใช้ Logcat

ถ้านักพัฒนาใช้ Virtual Device อย่าง Android Emulator มักจะไม่ต้องทำอะไรในขั้นตอนนี้ แต่ถ้าใช้ Physical Device หรืออุปกรณ์แอนดรอยด์ของจริงก็จะต้องทำขั้นตอนเหล่านี้ให้เรียบร้อยก่อน

  • เปิด Developer options
  • เปิดใช้งาน USB debugging ที่อยู่ใน Developer options
  • เชื่อมต่ออุปกรณ์แอนดรอยด์เข้ากับคอมพิวเตอร์

นั่นก็เพราะว่าการทำงานของ Logcat จะใช้ความสามารถของ ADB หรือ Android Debug Bridge ที่ต้องเปิดใช้งานจากเมนู USB debugging ใน Developer options นั่นเอง

Logcat อยู่ตรงไหนของ Android Studio ?

ใน Android Studio เวอร์ชันล่าสุด Logcat จะอยู่ที่ซ้ายล่างของหน้าต่างโปรแกรม โดยสังเกตได้จากไอคอนตามภาพตัวอย่างข้างล่าง

เมื่อกดเปิดเมนู Logcat ขึ้นมา ก็จะเห็นหน้าต่างแสดงขึ้นมาประมาณนี้

ซึ่งข้อมูลที่แสดงอยู่ในหน้าต่างดังกล่าวคือ Log ที่มาจากอุปกรณ์แอนดรอยด์ที่เชื่อมต่ออยู่นั่นเอง

ถ้า Log ไม่แสดงใน Logcat อาจจะเป็นเพราะอุปกรณ์แอนดรอยด์ยังไม่ได้เชื่อมต่อกับคอมพิวเตอร์ผ่าน ADB

การใช้งาน Logcat บนแอนดรอยด์

Logcat จะช่วยให้นักพัฒนาดู Log จากการทำงานของอุปกรณ์แอนดรอยด์ได้ง่ายขึ้น เช่น สถานะของข้อมูลบางอย่างภายในโค้ด, การรับส่งข้อมูลระหว่างตัวเครื่องกับ Web Service, หรือการทำงานของ OS เอง เป็นต้น ซึ่ง Log เหล่านี้จะมาจากโค้ดที่นักพัฒนาแอปต่าง ๆ ใส่ไว้นั่นเอง

โดยในปัจจุบัน Logcat เป็นเวอร์ชัน 2 แล้ว และมีรูปแบบแตกต่างไปจากเวอร์ชันเก่าพอสมควร โดยเจ้าของบล็อกเขียนแยกไว้เป็นบทความการใช้งาน Logcat v2 บน Android Studio ลองตามไปอ่านกันได้ว่าใช้งานยังไง

การใช้งาน Logcat v2 บน Android Studio
นับจาก Android Studio Dolphin เป็นต้นมา ทีมพัฒนาก็ได้ปรับปรุงหน้าต่าง Logcat ที่ว่าใหม่ทั้งหมดจนกลายออกมาเป็น Logcat v2 ที่มีรูปแบบการใช้งานแตกต่างไปจากเดิมพอสมควร

การแสดง Log บนแอนดรอยด์

นักพัฒนาสามารถใช้คลาส Log (android.util.Log) เพื่อให้แอปส่งข้อมูลออกไปที่ Log ได้ โดยจะมีรูปแบบการเรียกใช้งานแบบนี้

Log.v("Tag", "Message")
Log.d("Tag", "Message")
Log.i("Tag", "Message")
Log.w("Tag", "Message")
Log.e("Tag", "Message")
Log.wtf("Tag", "Message")

คำสั่ง Log ทุกตัวจะประกอบไปด้วย Parameter หลักๆ 2 ตัวด้วยกันคือ Tag และ Message ที่เป็น String ทั้งคู่

  • Tag คือหัวข้อกำกับของ Log นั้นๆ กำหนดเป็นอะไรก็ได้ไม่มีข้อจำกัดตายตัว
  • Message คือข้อความของ Log นั้นๆ กำหนดเป็นอะไรก็ได้เช่นกัน ไม่ต่างจาก Tag

นักพัฒนาจะต้องเป็นคนกำหนดเองว่าจะให้แสดงข้อความอะไร ซึ่ง Tag จะนิยมกำหนดเป็นหัวข้อของ Log นั้นๆ ส่วน Message ก็คือข้อความและข้อมูลการทำงานของโค้ดที่อยากจะให้แสดงออกมา

ตัวอย่างการใช้คำสั่ง Log

จุดประสงค์ของการใช้คำสั่ง Log คือ “อยากจะรู้อะไร ก็ให้แสดงมันออกมาซะ” ดังนั้นจึงไม่มีการกำหนดรูปแบบตายตัวว่าจะต้องแสดงอะไรใน Logcat

ยกตัวอย่างเช่น

// MainActivity.kt
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        /* ... */
        Log.d("Awesome Tag", "Very useful message")
    }
}

เมื่อแอปทำงานก็จะเห็น Log ตัวนี้โผล่ขึ้นมาใน Logcat ทันที

โดย Log ที่แสดงใน Logcat จะประกอบไปด้วย

ประเภทของ Log

นอกจากการใช้ Log จะช่วยแสดงข้อมูลที่ต้องการแล้ว Log ยังถูกแบ่งออกเป็นหลายประเภทเพื่อให้นักพัฒนาสามารถแยกประเภทของ Log ให้เหมาะสมกับแต่ละกรณีได้มากขึ้น

โดย Log จะถูกแบ่งออกเป็น 5 ประเภทดังนี้

  • Verbose (V) ใช้แสดงข้อความที่ไม่ค่อยสำคัญมากนัก
  • Debug (D) ใช้แสดงข้อความสำหรับการ Debug
  • Info (I) ใช้แสดงข้อความสำหรับแสดงข้อมูลการทำงานบางอย่าง
  • Warning (W) ใช้แสดงข้อผิดพลาดในการทำงานของโค้ดที่ไม่ร้ายแรง (แค่เตือน)
  • Error (E) ใช้แสดงข้อผิดพลาดในการทำงานของโค้ด

และนักพัฒนายังสามารถเปลี่ยนสีของ Log แต่ละประเภทเพื่อช่วยให้ดูได้ง่ายขึ้นได้อีกด้วย

เปลี่ยนสีให้กับ Logcat บน Android Studio
มาเปลี่ยนสีให้กับ Logcat ใน Android Studio ให้มีสีสันยิ่งขึ้นกันเถอะ

Logcat แสดงสาเหตุของปัญหาให้ทุกครั้งที่ Force Close (แอปพัง)

ถ้ามั่นใจว่าเขียนโค้ดถูกต้อง (อย่างน้อยก็ Syntax ถูก) แต่เมื่อลองใช้งานแอปไปได้ซักพักก็เจอปัญหาว่าแอปปิดตัวลง ซึ่งเป็นเรื่องปกติที่นักพัฒนาแอนดรอยด์ทุกคนจะได้เจอ ซึ่งปัญหานี้เกิดมาจาก Runtime Error จนทำให้เกิด Force Close หรือแอปพังจนปิดตัวเองนั่นเอง

เมื่อเกิดปัญหาแบบนี้ สิ่งสำคัญที่นักพัฒนาจะต้องรู้ให้ได้เลยก็คือ "ปัญหาเกิดมาจากอะไร" โดยใช้ Logcat เพื่อดู Error Log ที่เกิดขึ้น ณ ตอนนั้น

ภาพตัวอย่างข้างบนคือ Error Log ที่แสดงใน Logcat ตอนที่แอปพัง ซึ่งข้อความเหล่านี้จะบอกปัญหาที่ทำให้แอปถูก Force Close นั่นเอง อีกทั้งยังบอกให้ด้วยว่าโค้ดบรรทัดไหนในไฟล์ไหนที่ทำให้เกิดปัญหาดังกล่าว

จากตัวอย่างจะเห็นว่าปัญหาคือ NullPointerException ที่เกิดขึ้นใน MainActivity.kt บรรทัดที่ 43 โดยสามารถกดที่ตัวหนังสือสีน้ำเงินดังกล่าวเพื่อไปที่ไฟล์ดังกล่าวได้ในทันที เพื่อวิเคราะห์ปัญหาต่อไปว่าเกิดจากอะไร และทำการแก้ไขให้เรียบร้อย

ปกติใช้ Logcat ทำอะไรกันบ้าง?

Logcat เป็นเครื่องมือที่ทรงพลังมากสำหรับนักพัฒนาแอนดรอยด์ ดังนั้นเรามาดูกันว่าส่วนใหญ่เราใช้ Logcat ทำอะไรกัน

ศึกษาหรือตรวจสอบการทำงานของโค้ด

เมื่อใดที่อยากรู้ว่าโค้ดตรงไหนทำงานก่อนหรือหลัง และโค้ดตรงไหนถูกเรียกบ้าง ก็ให้ลองใส่คำสั่ง Log ลงไปตรง ๆ ได้เลย แล้วตอนที่แอปทำงานก็จะเห็น Log เหล่านั้นจาก Logcat

ยกตัวอย่างเช่น ต้องการรู้ลำดับการทำงานของ Activity Lifecycle

// MainActivity.kt
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        /* ... */
        Log.d("MainActivity", "onCreate")
    }

    override fun onStart() {
        /* ... */
        Log.d("MainActivity", "onStart")
    }

    override fun onResume() {
        /* ... */
        Log.d("MainActivity", "onResume")
    }

    override fun onPause() {
        /* ... */
        Log.d("MainActivity", "onPause")
    }

    override fun onStop() {
        /* ... */
        Log.d("MainActivity", "onStop")
    }

    override fun onDestroy() {
        /* ... */
        Log.d("MainActivity", "onDestroy")
    }

    override fun onRestart() {
        /* ... */
        Log.d("MainActivity", "onRestart")
    }
}

ตรวจสอบ Fatal Error หรือ Runtime Exception

จากที่อธิบายไปก่อนหน้านี้ว่าเวลาที่แอปมีปัญหาแล้ว Force Close การใช้ Logcat จะช่วยแสดง Error Log ที่เกี่ยวข้องออกมาเพื่อช่วยให้นักพัฒนาตรวจสอบปัญหาได้ง่ายขึ้น และถ้าอ่านแล้วยังไม่เข้าใจ ก็สามารถเอาไปถามหรือค้นหาต่อในอินเตอร์เน็ตได้

ตรวจสอบเงื่อนไขหรือค่าต่าง ๆ ในโค้ด

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

fun onTouchEvent(event: MotionEvent): Boolean {
    Log.d("Touch Event", "Position : ${event.x}, ${event.y}")
    when (event.action) {
        MotionEvent.ACTION_DOWN -> Log.d("Touch Event", "Action Down")
        MotionEvent.ACTION_MOVE -> Log.d("Touch Event", "Action Move")
        MotionEvent.ACTION_UP -> Log.d("Touch Event", "Action Up")
    }
    return true
}

Logcat มีไว้ให้คนอ่าน จงทำให้มันเข้าใจง่าย

การแสดงข้อความใดๆผ่านคำสั่ง Log ทุกครั้ง ควรเป็นข้อความที่ “เข้าใจง่าย”, “ดูไม่ยาก” และ “ไม่ปนกันมั่ว” เพราะตัวเราเองนั่นแหละที่ต้องมานั่งดู Logcat

  • อย่าแสดงแค่ตัวเลข แต่ไม่บอกว่ามันคืออะไร
  • อย่าแสดงข้อความที่ไม่จำเป็น หรืออ่านแล้วไม่เข้าใจว่าจะสื่ออะไร
  • แสดง Log ให้น้อยบรรทัดที่สุด
  • พยายามทำให้ดูแล้วเข้าใจง่ายที่สุด
  • แยกประเภทของ Log ให้ถูกต้อง
  • ตอนทำเป็น Production ถ้ามี Log อันไหนไม่อยากให้แสดงก็อย่าลืมเอาออกด้วย

จัดการ Log อย่างมีประสิทธิภาพมากขึ้นด้วย Timber

Timber เป็น Library ที่จะช่วยให้นักพัฒนาสามารถจัดการ Log บนแอนดรอยด์ได้สะดวกขึ้น สามารถซ่อน Log ที่ไม่จำเป็นออกจาก Production Build ได้โดยไม่ต้องลบโค้ดเหล่านั้นออก

GitHub - JakeWharton/timber: A logger with a small, extensible API which provides utility on top of Android’s normal Log class.
A logger with a small, extensible API which provides utility on top of Android’s normal Log class. - JakeWharton/timber

สรุป

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

  • ควรใส่คำสั่งไว้ตรงไหน?
  • ควรแสดงข้อมูลอะไร?
  • วิเคราะห์ปัญหาจาก Error Log

ดังนั้น Logcat จึงเป็นเครื่องมือที่นักพัฒนาควรฝึกใช้งานให้ชำนาญ​ เพราะไม่ว่าจะพัฒนาแอปบนแอนดรอยด์เชี่ยวชาญแค่ไหน สุดท้ายก็ยังต้องพึ่งเจ้าเครื่องมือตัวนี้อยู่ดี

และสุดท้ายนี้ก็ขอกล่าวจบท้ายบทความนี้ไว้ว่า

“ชนใดไม่เคยใช้ Logcat แปลว่าชนนั้นไม่เคยเขียนโค้ดแอนดรอยด์ด้วยตนเอง”