รับรายงานข้อขัดข้อง NDK ของ Android

หากแอป Android มีไลบรารีเนทีฟ คุณก็เปิดใช้สแต็กเทรซทั้งสแต็กและรายงานข้อขัดข้องโดยละเอียดสำหรับโค้ดเนทีฟจาก Firebase Crashlytics ได้ด้วยการอัปเดตการกำหนดค่าบิลด์ของแอปเล็กน้อย

คำแนะนำนี้อธิบายวิธีกำหนดค่ารายงานข้อขัดข้องด้วย Firebase Crashlytics SDK สำหรับ NDK

หากกำลังมองหาวิธีเริ่มต้นใช้งาน Crashlytics ในโปรเจ็กต์ Unity โปรดอ่านคู่มือเริ่มต้นใช้งาน Unity

ก่อนเริ่มต้น

  1. เพิ่ม Firebase ลงในโปรเจ็กต์ Android หากยังไม่ได้เพิ่ม หากไม่มีแอป Android คุณสามารถดาวน์โหลด แอปตัวอย่างได้

  2. แนะนำ: หากต้องการรับบันทึกเบรดครัมบ์โดยอัตโนมัติ คุณต้องเปิดใช้ Google Analytics ในโปรเจ็กต์ Firebase เพื่อทำความเข้าใจการดำเนินการของผู้ใช้ที่นำไปสู่เหตุการณ์ข้อขัดข้อง ไม่ร้ายแรง หรือ ANR

    • หากโปรเจ็กต์ Firebase ที่มีอยู่ไม่ได้เปิดใช้ Google Analytics คุณเปิดใช้ Google Analytics ได้จากแท็บการผสานรวมของ > การตั้งค่าโปรเจ็กต์ในคอนโซล Firebase

    • หากคุณกำลังสร้างโปรเจ็กต์ Firebase ใหม่ ให้เปิดใช้ Google Analytics ในระหว่างกระบวนการสร้างโปรเจ็กต์

  3. ตรวจสอบว่าแอปมีเวอร์ชันขั้นต่ำที่จำเป็นต่อไปนี้

    • Gradle 8.0
    • ปลั๊กอิน Android Gradle 8.1.0
    • ปลั๊กอิน Gradle 4.4.1 สำหรับบริการของ Google

ขั้นตอนที่ 1: เพิ่ม Crashlytics SDK สำหรับ NDK ลงในแอป

ในไฟล์ Gradle ของโมดูล (ระดับแอป) (โดยทั่วไปจะเป็น <project>/<app-module>/build.gradle.kts หรือ <project>/<app-module>/build.gradle) ให้เพิ่มทรัพยากร Dependency สำหรับไลบรารี Crashlytics NDK สำหรับ Android เราขอแนะนำให้ใช้ Firebase Android BoM เพื่อควบคุมการกำหนดเวอร์ชันไลบรารี

เราแนะนำให้เปิดใช้ Google Analytics ในโปรเจ็กต์ Firebase และเพิ่ม Firebase SDK สำหรับ Google Analytics ลงในแอปเพื่อประสบการณ์การใช้งาน Crashlytics ที่ดีที่สุด

dependencies {
    // Import the BoM for the Firebase platform
    implementation(platform("com.google.firebase:firebase-bom:33.1.0"))

    // Add the dependencies for the Crashlytics NDK and Analytics libraries
    // When using the BoM, you don't specify versions in Firebase library dependencies
    implementation("com.google.firebase:firebase-crashlytics-ndk")
    implementation("com.google.firebase:firebase-analytics")
}

การใช้ Firebase Android BoM จะทำให้ แอปใช้ไลบรารี Firebase Android เวอร์ชันที่เข้ากันได้เสมอ

(ทางเลือก) เพิ่มทรัพยากร Dependency ของไลบรารี Firebase โดยไม่ต้องใช้ BoM

หากเลือกไม่ใช้ Firebase BoM คุณต้องระบุเวอร์ชันไลบรารี Firebase แต่ละเวอร์ชันในบรรทัดทรัพยากร Dependency

โปรดทราบว่าหากคุณใช้ไลบรารี Firebase หลายในแอป เราขอแนะนำให้ใช้ BoM ในการจัดการเวอร์ชันไลบรารีซึ่งจะดูแลให้ทุกเวอร์ชันทำงานร่วมกันได้

dependencies {
    // Add the dependencies for the Crashlytics NDK and Analytics libraries
    // When NOT using the BoM, you must specify versions in Firebase library dependencies
    implementation("com.google.firebase:firebase-crashlytics-ndk:19.0.1")
    implementation("com.google.firebase:firebase-analytics:22.0.1")
}
หากกำลังมองหาโมดูลไลบรารีสำหรับ Kotlin โดยเฉพาะ ตั้งแต่ เดือนตุลาคม 2023 (Firebase BoM 32.5.0) ทั้งนักพัฒนา Kotlin และ Java จะ ขึ้นอยู่กับโมดูลไลบรารีหลัก (ดูรายละเอียดได้ที่ คําถามที่พบบ่อยเกี่ยวกับโครงการริเริ่มนี้)

ขั้นตอนที่ 2: เพิ่มปลั๊กอิน Crashlytics Gradle ลงในแอป

  1. ในไฟล์ Gradle ระดับราก (ระดับโปรเจ็กต์) (<project>/build.gradle.kts หรือ <project>/build.gradle) ให้เพิ่มปลั๊กอิน Crashlytics Gradle ลงในบล็อก plugins ดังนี้

    Kotlin

    plugins {
        // Make sure that you have the AGP plugin 8.1+ dependency
        id("com.android.application") version "8.1.4" apply false
        // ...
    
        // Make sure that you have the Google services Gradle plugin 4.4.1+ dependency
        id("com.google.gms.google-services") version "4.4.2" apply false
    
        // Add the dependency for the Crashlytics Gradle plugin
        id("com.google.firebase.crashlytics") version "3.0.1" apply false
    }
    

    Groovy

    plugins {
        // Make sure that you have the AGP plugin 8.1+ dependency
        id 'com.android.application' version '8.1.4' apply false
        // ...
    
        // Make sure that you have the Google services Gradle plugin 4.4.1+ dependency
        id 'com.google.gms.google-services' version '4.4.2' apply false
    
        // Add the dependency for the Crashlytics Gradle plugin
        id 'com.google.firebase.crashlytics' version '3.0.1' apply false
    }
    
  2. ในไฟล์ Gradle ของโมดูล (ระดับแอป) (โดยทั่วไปจะเป็น <project>/<app-module>/build.gradle.kts หรือ <project>/<app-module>/build.gradle) ให้ติดตั้งปลั๊กอิน Crashlytics Gradle ดังนี้

    Kotlin

    plugins {
      id("com.android.application")
      // ...
    
      // Make sure that you have the Google services Gradle plugin
      id("com.google.gms.google-services")
    
      // Add the Crashlytics Gradle plugin
      id("com.google.firebase.crashlytics")
    }

    Groovy

    plugins {
      id 'com.android.application'
      // ...
    
      // Make sure that you have the Google services Gradle plugin
      id 'com.google.gms.google-services'
    
      // Add the Crashlytics Gradle plugin
      id 'com.google.firebase.crashlytics'
    }

ขั้นตอนที่ 3: เพิ่มส่วนขยาย Crashlytics ลงในบิลด์

ในไฟล์ Gradle ของโมดูล (ระดับแอป) (โดยทั่วไปจะเป็น <project>/<app-module>/build.gradle.kts หรือ <project>/<app-module>/build.gradle) ให้กำหนดค่าส่วนขยาย Crashlytics

Kotlin

import com.google.firebase.crashlytics.buildtools.gradle.CrashlyticsExtension

// ...

android {
  // ...
  buildTypes {
      getByName("release") {
          // Add this extension
          configure<CrashlyticsExtension> {
              // Enable processing and uploading of native symbols to Firebase servers.
              // By default, this is disabled to improve build speeds.
              // This flag must be enabled to see properly-symbolicated native
              // stack traces in the Crashlytics dashboard.
              nativeSymbolUploadEnabled = true
          }
      }
  }
}

Groovy

// ...

android {
  // ...
  buildTypes {
      release {
          // Add this extension
          firebaseCrashlytics {
              // Enable processing and uploading of native symbols to Firebase servers.
              // By default, this is disabled to improve build speeds.
              // This flag must be enabled to see properly-symbolicated native
              // stack traces in the Crashlytics dashboard.
              nativeSymbolUploadEnabled true
          }
      }
  }
}

ขั้นตอนที่ 4: ตั้งค่าการอัปโหลดสัญลักษณ์เนทีฟโดยอัตโนมัติ

Crashlytics จำเป็นต้องรู้เกี่ยวกับสัญลักษณ์ในไบนารีของระบบเพื่อสร้างสแต็กเทรซที่อ่านได้จากข้อขัดข้องของ NDK ปลั๊กอิน Crashlytics Gradle มีงาน uploadCrashlyticsSymbolFileBUILD_VARIANT เพื่อทำให้กระบวนการนี้เป็นไปโดยอัตโนมัติ

  1. โปรดตรวจสอบว่าได้ตั้งค่า nativeSymbolUploadEnabled เป็น true ในไฟล์ Gradle ของโมดูล (ระดับแอป) เพื่อให้คุณเข้าถึงงานสำหรับการอัปโหลดสัญลักษณ์อัตโนมัติได้

  2. หากต้องการให้ชื่อเมธอดปรากฏในสแต็กเทรซ คุณต้องเรียกใช้งาน uploadCrashlyticsSymbolFileBUILD_VARIANT อย่างชัดแจ้งหลังจากบิลด์แต่ละรายการของไลบรารี NDK เช่น

    >./gradlew app:assembleBUILD_VARIANT\
               app:uploadCrashlyticsSymbolFileBUILD_VARIANT
    
  3. ทั้ง Crashlytics SDK สำหรับ NDK และปลั๊กอิน Crashlytics Gradle ขึ้นอยู่กับการมีอยู่ของรหัสบิลด์ GNU ภายในออบเจ็กต์ที่แชร์แบบเนทีฟ

    คุณยืนยันว่ามีรหัสนี้ได้โดยการเรียกใช้ readelf -n ในไบนารีแต่ละรายการ หากไม่มีรหัสบิลด์ ให้เพิ่ม -Wl,--build-id ลงในแฟล็กของระบบบิลด์เพื่อแก้ไขปัญหา

ขั้นตอนที่ 5: บังคับให้การทดสอบขัดข้องเพื่อตั้งค่าให้เสร็จสิ้น

คุณต้องบังคับให้การทดสอบขัดข้องเพื่อตั้งค่า Crashlytics ให้เสร็จสิ้นและดูข้อมูลเบื้องต้นในแดชบอร์ดของ Crashlytics ของคอนโซล Firebase

  1. เพิ่มโค้ดลงในแอปของคุณที่ใช้บังคับให้การทดสอบขัดข้องได้

    คุณใช้โค้ดต่อไปนี้ใน MainActivity ของแอปเพื่อเพิ่มปุ่มลงในแอปได้ ซึ่งจะทําให้เกิดข้อขัดข้องเมื่อกดปุ่ม โดยปุ่มจะมีป้ายกำกับว่า "ทดสอบข้อขัดข้อง"

    Kotlin+KTX

    val crashButton = Button(this)
    crashButton.text = "Test Crash"
    crashButton.setOnClickListener {
       throw RuntimeException("Test Crash") // Force a crash
    }
    
    addContentView(crashButton, ViewGroup.LayoutParams(
           ViewGroup.LayoutParams.MATCH_PARENT,
           ViewGroup.LayoutParams.WRAP_CONTENT))
    

    Java

    Button crashButton = new Button(this);
    crashButton.setText("Test Crash");
    crashButton.setOnClickListener(new View.OnClickListener() {
       public void onClick(View view) {
           throw new RuntimeException("Test Crash"); // Force a crash
       }
    });
    
    addContentView(crashButton, new ViewGroup.LayoutParams(
           ViewGroup.LayoutParams.MATCH_PARENT,
           ViewGroup.LayoutParams.WRAP_CONTENT));
    
  2. สร้างและเรียกใช้แอป

  3. บังคับใช้ข้อขัดข้องจากการทดสอบเพื่อส่งรายงานข้อขัดข้องครั้งแรกของแอป

    1. เปิดแอปจากอุปกรณ์ทดสอบหรือโปรแกรมจำลอง

    2. ในแอป ให้กดปุ่ม "ทดสอบข้อขัดข้อง" ที่เพิ่มไว้โดยใช้โค้ดด้านบน

    3. หลังจากที่แอปขัดข้อง ให้รีสตาร์ทเพื่อให้แอปส่งรายงานข้อขัดข้องไปยัง Firebase ได้

  4. ไปที่แดชบอร์ด Crashlytics ของคอนโซล Firebase เพื่อดูข้อขัดข้องในการทดสอบ

    หากคุณรีเฟรชคอนโซลแล้ว แต่ยังไม่เห็นข้อขัดข้องจากการทดสอบหลังจากผ่านไป 5 นาที ให้เปิดใช้การบันทึกการแก้ไขข้อบกพร่อง เพื่อดูว่าแอปส่งรายงานข้อขัดข้องหรือไม่


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

ขั้นตอนถัดไป

  • (แนะนำ) รับความช่วยเหลือในการแก้ไขข้อบกพร่องของข้อขัดข้องที่เกิดจากข้อผิดพลาดด้านหน่วยความจําของระบบโดยการรวบรวมรายงาน GWP-ASan ข้อผิดพลาดเกี่ยวกับหน่วยความจำเหล่านี้อาจเกี่ยวข้องกับความเสียหายของหน่วยความจำภายในแอป ซึ่งเป็นสาเหตุหลักของช่องโหว่ด้านความปลอดภัยของแอป หากต้องการใช้ประโยชน์จากฟีเจอร์การแก้ไขข้อบกพร่องนี้ ให้ตรวจสอบว่าแอปของคุณเปิดใช้ GWP-ASan อย่างชัดแจ้ง และใช้ Crashlytics SDK ล่าสุดสำหรับ NDK (v18.3.6 ขึ้นไป หรือ Firebase BoM v31.3.0 ขึ้นไป)

  • ปรับแต่งการตั้งค่ารายงานข้อขัดข้อง โดยเพิ่มการรายงานการเลือกใช้ บันทึก คีย์ และการติดตามข้อผิดพลาดที่ไม่ร้ายแรง

  • ผสานรวมกับ Google Play เพื่อให้คุณกรองรายงานข้อขัดข้องของแอป Android ตามแทร็ก Google Play ได้โดยตรงในแดชบอร์ด Crashlytics ซึ่งจะช่วยให้คุณมุ่งเน้นแดชบอร์ดไปยังบิลด์ที่เฉพาะเจาะจงได้ดียิ่งขึ้น

การแก้ปัญหา

หากคุณเห็นสแต็กเทรซที่ต่างกันในคอนโซล Firebase และใน Logcat โปรดดูคู่มือการแก้ปัญหา



ตัวเลือกอื่นๆ สำหรับการอัปโหลดสัญลักษณ์

เวิร์กโฟลว์หลักในหน้านี้ด้านบนใช้ได้กับบิลด์ Gradle มาตรฐาน อย่างไรก็ตาม แอปบางแอปใช้การกำหนดค่าหรือเครื่องมือที่แตกต่างกัน (เช่น กระบวนการบิลด์ที่ไม่ใช่ Gradle) ในกรณีเหล่านี้ ตัวเลือกต่อไปนี้อาจเป็นประโยชน์ ในการอัปโหลดสัญลักษณ์ให้สำเร็จ

ตัวเลือก: อัปโหลดสัญลักษณ์สำหรับโมดูลไลบรารีและทรัพยากร Dependency ภายนอก

ตัวเลือกนี้จะมีประโยชน์ในสถานการณ์ต่อไปนี้

  • หากคุณใช้กระบวนการบิลด์ NDK ที่กำหนดเองใน Gradle
  • หากไลบรารีแบบเนทีฟสร้างขึ้นในโมดูล ไลบรารี/ฟีเจอร์หรือให้บริการโดยบุคคลที่สาม
  • หากงานการอัปโหลดสัญลักษณ์อัตโนมัติล้มเหลวหรือคุณเห็นข้อขัดข้องที่ไม่มีสัญลักษณ์ในหน้าแดชบอร์ด

ตัวเลือก: อัปโหลดสัญลักษณ์สำหรับบิลด์ที่ไม่ใช่ Gradle หรือไลบรารีเนทีฟที่ไม่ได้ Strip เข้าซึ่งเข้าถึงไม่ได้

ตัวเลือกนี้จะมีประโยชน์ในสถานการณ์ต่อไปนี้

  • หากใช้กระบวนการบิลด์ที่ไม่ใช่ Gradle

  • หากระบบส่งไลบรารีเนทีฟที่ไม่ได้ Strip ให้คุณในลักษณะที่เข้าถึงไม่ได้ระหว่างบิลด์ Gradle