Nhận báo cáo sự cố về Android NDK

Nếu ứng dụng Android của bạn chứa thư viện gốc, bạn có thể bật dấu vết ngăn xếp đầy đủ và báo cáo sự cố chi tiết cho mã gốc từ Firebase Crashlytics bằng một vài bản cập nhật nhỏ đối với cấu hình bản dựng của ứng dụng.

Hướng dẫn này mô tả cách định cấu hình tính năng báo cáo sự cố bằng SDK Firebase Crashlytics cho NDK.

Nếu bạn đang tìm cách bắt đầu sử dụng Crashlytics trong các dự án Unity, hãy xem Hướng dẫn bắt đầu sử dụng Unity.

Trước khi bắt đầu

  1. Thêm Firebase vào dự án Android nếu bạn chưa thực hiện. Nếu không có ứng dụng Android, bạn có thể tải một ứng dụng mẫu xuống.

  2. Đề xuất: Để tự động nhận nhật ký đường dẫn nhằm hiểu rõ các hành động của người dùng dẫn đến sự cố, sự cố không nghiêm trọng hoặc sự kiện ANR, bạn cần bật Google Analytics trong dự án Firebase.

    • Nếu dự án Firebase hiện tại của bạn chưa bật Google Analytics, bạn có thể bật Google Analytics từ thẻ Tích hợp của > Cài đặt dự án trong bảng điều khiển Firebase.

    • Nếu bạn đang tạo dự án Firebase mới, hãy bật Google Analytics trong quy trình tạo dự án.

  3. Đảm bảo ứng dụng của bạn có các phiên bản tối thiểu bắt buộc sau:

    • Gradle 8.0
    • Trình bổ trợ Android cho Gradle 8.1.0
    • Trình bổ trợ Google services cho Gradle 4.4.1

Bước 1: Thêm SDK Crashlytics cho NDK vào ứng dụng

Trong tệp Gradle (ở cấp ứng dụng) của mô-đun (thường là <project>/<app-module>/build.gradle.kts hoặc <project>/<app-module>/build.gradle), hãy thêm phần phụ thuộc cho thư viện NDK Crashlytics cho Android. Bạn nên sử dụng Firebase Android BoM để kiểm soát việc tạo phiên bản thư viện.

Để có trải nghiệm tối ưu với Crashlytics, bạn nên bật Google Analytics trong dự án Firebase và thêm SDK Firebase cho Google Analytics vào ứng dụng.

dependencies {
    // Import the BoM for the Firebase platform
    implementation(platform("com.google.firebase:firebase-bom:33.9.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")
}

Bằng cách sử dụng Firebase Android BoM, ứng dụng của bạn sẽ luôn sử dụng những phiên bản tương thích của thư viện Android trên Firebase.

Nếu chọn không sử dụng Firebase BoM, bạn phải chỉ định từng phiên bản thư viện Firebase trong dòng phần phụ thuộc của thư viện đó.

Xin lưu ý rằng nếu bạn sử dụng nhiều thư viện Firebase trong ứng dụng, bạn nên sử dụng BoM để quản lý các phiên bản thư viện, nhằm đảm bảo rằng tất cả các phiên bản đều tương thích.

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.4.0")
    implementation("com.google.firebase:firebase-analytics:22.2.0")
}
Bạn đang tìm một mô-đun thư viện dành riêng cho Kotlin? Kể từ tháng 10 năm 2023 (Firebase BoM 32.5.0), cả nhà phát triển Kotlin và Java đều có thể phụ thuộc vào mô-đun thư viện chính (để biết thông tin chi tiết, hãy xem Câu hỏi thường gặp về sáng kiến này).

Bước 2: Thêm trình bổ trợ Gradle Crashlytics vào ứng dụng

  1. Trong tệp Gradle cấp gốc (cấp dự án) (<project>/build.gradle.kts hoặc <project>/build.gradle), hãy thêm trình bổ trợ Gradle Crashlytics vào khối plugins:

    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.3" apply false
    }
    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.3' apply false
    }
  2. Trong tệp Gradle mô-đun (cấp ứng dụng) (thường là <project>/<app-module>/build.gradle.kts hoặc <project>/<app-module>/build.gradle), hãy thêm trình bổ trợ Gradle Crashlytics:

    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")
    }
    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'
    }

Bước 3: Thêm tiện ích Crashlytics vào bản dựng

Trong tệp Gradle mô-đun (cấp ứng dụng) (thường là <project>/<app-module>/build.gradle.kts hoặc <project>/<app-module>/build.gradle), hãy định cấu hình tiện ích Crashlytics.

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
          }
      }
  }
}
// ...

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
          }
      }
  }
}

Bước 4: Thiết lập tính năng tự động tải biểu tượng gốc lên

Để tạo dấu vết ngăn xếp có thể đọc được từ các sự cố NDK, Crashlytics cần biết về các biểu tượng trong tệp nhị phân gốc của bạn. Trình bổ trợ Gradle Crashlytics bao gồm tác vụ uploadCrashlyticsSymbolFileBUILD_VARIANT để tự động hoá quy trình này.

  1. Để bạn có thể truy cập vào tác vụ tải biểu tượng lên tự động, hãy đảm bảo rằng nativeSymbolUploadEnabled được đặt thành true trong tệp Gradle của mô-đun (cấp ứng dụng).

  2. Để tên phương thức xuất hiện trong dấu vết ngăn xếp, bạn phải gọi rõ ràng tác vụ uploadCrashlyticsSymbolFileBUILD_VARIANT sau mỗi bản dựng của thư viện NDK. Ví dụ:

    >./gradlew app:assembleBUILD_VARIANT\
               app:uploadCrashlyticsSymbolFileBUILD_VARIANT
  3. Cả SDK Crashlytics cho NDK và trình bổ trợ Gradle Crashlytics đều phụ thuộc vào sự hiện diện của mã bản dựng GNU trong các đối tượng dùng chung gốc.

    Bạn có thể xác minh sự hiện diện của mã nhận dạng này bằng cách chạy readelf -n trên mỗi tệp nhị phân. Nếu không có mã bản dựng, hãy thêm -Wl,--build-id vào cờ của hệ thống xây dựng để khắc phục sự cố.

Bước 5: Buộc sự cố kiểm thử để hoàn tất việc thiết lập

Để hoàn tất việc thiết lập Crashlytics và xem dữ liệu ban đầu trong trang tổng quan Crashlytics của bảng điều khiển Firebase, bạn cần buộc một sự cố kiểm thử.

  1. Thêm mã vào ứng dụng mà bạn có thể dùng để buộc xảy ra sự cố kiểm thử.

    Bạn có thể sử dụng mã sau trong MainActivity của ứng dụng để thêm một nút vào ứng dụng. Khi nhấn nút này, ứng dụng sẽ gặp sự cố. Nút này có nhãn "Test Crash" (Kiểm thử sự cố).

    KotlinJava
    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))
    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. Tạo bản dựng và chạy ứng dụng.

  3. Buộc sự cố kiểm thử xảy ra để gửi báo cáo sự cố đầu tiên của ứng dụng:

    1. Mở ứng dụng trên thiết bị kiểm thử hoặc trình mô phỏng.

    2. Trong ứng dụng, hãy nhấn vào nút "Test Crash" (Kiểm thử sự cố) mà bạn đã thêm bằng mã ở trên.

    3. Sau khi ứng dụng gặp sự cố, hãy khởi động lại ứng dụng để ứng dụng có thể gửi báo cáo sự cố đến Firebase.

  4. Chuyển đến trang tổng quan Crashlytics của bảng điều khiển Firebase để xem sự cố kiểm thử.

    Nếu bạn đã làm mới bảng điều khiển và vẫn không thấy sự cố kiểm thử sau 5 phút, hãy bật tính năng ghi nhật ký gỡ lỗi để xem ứng dụng của bạn có gửi báo cáo sự cố hay không.


Vậy là xong! Crashlytics hiện đang theo dõi sự cố trong ứng dụng của bạn. Bạn có thể xem và điều tra báo cáo sự cố cũng như số liệu thống kê trong trang tổng quan Crashlytics.

Các bước tiếp theo

  • (Nên dùng) Yêu cầu trợ giúp gỡ lỗi sự cố do lỗi bộ nhớ gốc gây ra bằng cách thu thập báo cáo GWP-ASan. Các lỗi liên quan đến bộ nhớ này có thể liên quan đến tình trạng hỏng bộ nhớ trong ứng dụng của bạn. Đây là nguyên nhân chính gây ra các lỗ hổng bảo mật của ứng dụng. Để tận dụng tính năng gỡ lỗi này, hãy đảm bảo ứng dụng của bạn đã bật GWP-ASan một cách rõ ràng và sử dụng SDK Crashlytics mới nhất cho NDK (phiên bản 18.3.6 trở lên hoặc Firebase BoM phiên bản 31.3.0 trở lên).

  • Tuỳ chỉnh chế độ thiết lập báo cáo sự cố bằng cách thêm tính năng báo cáo tuỳ chọn, nhật ký, khoá và tính năng theo dõi lỗi không nghiêm trọng.

  • Tích hợp với Google Play để bạn có thể lọc báo cáo sự cố của ứng dụng Android theo kênh Google Play ngay trong trang tổng quan Crashlytics. Nhờ đó, bạn có thể tập trung vào các bản dựng cụ thể trên trang tổng quan.

Khắc phục sự cố

Nếu bạn thấy các dấu vết ngăn xếp khác nhau trong bảng điều khiển Firebase và trong logcat, hãy tham khảo Hướng dẫn khắc phục sự cố.



Các lựa chọn thay thế để tải biểu tượng lên

Quy trình công việc chính trên trang này áp dụng cho các bản dựng Gradle chuẩn. Tuy nhiên, một số ứng dụng sử dụng cấu hình hoặc công cụ khác (ví dụ: quy trình tạo bản dựng không phải Gradle). Trong những trường hợp này, các tuỳ chọn sau đây có thể giúp bạn tải biểu tượng lên thành công.

Tuỳ chọn: Tải biểu tượng lên cho các mô-đun thư viện và phần phụ thuộc bên ngoài

Lựa chọn này có thể hữu ích trong các trường hợp sau:

  • Nếu bạn sử dụng quy trình tạo bản dựng NDK tuỳ chỉnh trong Gradle
  • Nếu thư viện gốc của bạn được tạo trong một mô-đun thư viện/tính năng hoặc do bên thứ ba cung cấp
  • Nếu tác vụ tự động tải biểu tượng lên không thành công hoặc bạn thấy các sự cố không được biểu tượng hoá trong trang tổng quan

Tác vụ tải biểu tượng Crashlytics lên tiêu chuẩn giả định rằng bạn đang tạo thư viện gốc trong bản dựng Gradle của mô-đun ứng dụng, sử dụng các công cụ bản dựng NDK tiêu chuẩn như CMake.

Tuy nhiên, nếu đang sử dụng quy trình tạo bản dựng NDK tuỳ chỉnh trong Gradle hoặc thư viện gốc được tạo trong mô-đun thư viện/tính năng hoặc do bên thứ ba cung cấp, thì bạn có thể cần chỉ định rõ ràng đường dẫn đến thư viện chưa bị loại bỏ. Để thực hiện việc này, bạn có thể thêm thuộc tính unstrippedNativeLibsDir trong tiện ích Crashlytics trong tệp bản dựng Gradle.

  1. Hãy đảm bảo rằng bạn đã hoàn tất các nhiệm vụ ban đầu sau đây trong quy trình công việc chính ở trên trang này:

    1. Bật Crashlytics trong bảng điều khiển Firebase.

    2. Thêm SDK Crashlytics cho NDKtrình bổ trợ Gradle Crashlytics.

    3. Thêm tiện ích Crashlytics vào bản dựng.

    4. Thiết lập tính năng tự động tải biểu tượng gốc lên.

  2. Để tác vụ tải biểu tượng tự động có thể tìm thấy thông tin biểu tượng, hãy thêm nội dung sau vào tệp Gradle của mô-đun (cấp ứng dụng) (thường là <project>/<app-module>/build.gradle.kts hoặc <project>/<app-module>/build.gradle):

    import com.google.firebase.crashlytics.buildtools.gradle.CrashlyticsExtension
    
    // ...
    
    android {
        // ...
        buildTypes {
            release {
                configure<CrashlyticsExtension> {
                    nativeSymbolUploadEnabled = true
                    unstrippedNativeLibsDir = file("PATH/TO/UNSTRIPPED/DIRECTORY")
                }
            }
        }
    }
    // ...
    
    android {
        // ...
        buildTypes {
            release {
                firebaseCrashlytics {
                    nativeSymbolUploadEnabled true
                    unstrippedNativeLibsDir file("PATH/TO/UNSTRIPPED/DIRECTORY")
                }
            }
        }
    }

    Trình bổ trợ Crashlytics sẽ tìm kiếm đệ quy thư mục đã chỉ định cho các thư viện gốc có đuôi .so. Sau đó, Crashlytics sẽ trích xuất các biểu tượng gỡ lỗi từ tất cả các thư viện đó và tải các biểu tượng đó lên máy chủ Firebase.

    Sau đây là những nội dung bạn có thể chỉ định trong thuộc tính unstrippedNativeLibsDir:

    • Mọi đối số được phép cho org.gradle.api.Project#files(Object...), bao gồm: java.lang.String, java.io.File hoặc org.gradle.api.file.FileCollection

    • Nhiều thư mục cho một phiên bản bản dựng bằng cách cung cấp danh sách hoặc bản sao FileCollection

    • (Kể từ trình bổ trợ Gradle Crashlytics phiên bản 3.0.0) Tích luỹ nhiều thư mục trong các sản phẩm riêng lẻ và tạo phiên bản.

      buildTypes {
        release {
          configure<CrashlyticsExtension> {
            nativeSymbolUploadEnabled = true
            unstrippedNativeLibsDir = file("MY/NATIVE/LIBS")
          }
        }
        productFlavors {
          flavorDimensions += "feature"
          create("basic") {
            dimension = "feature"
            // ...
          }
          create("featureX") {
            dimension = "feature"
            configure<CrashlyticsExtension> {
              unstrippedNativeLibsDir = file("MY/FEATURE_X/LIBS")
            }
          }
        }
      }
      

    Tác vụ uploadCrashlyticsSymbolFilesBasicRelease sẽ chỉ tải các biểu tượng lên trong MY/NATIVE/LIBS, nhưng uploadCrashlyticsSymbolFilesFeatureXRelease sẽ tải các biểu tượng lên cả MY/NATIVE/LIBSMY/FEATURE_X/LIBS.

  3. Cuối cùng, hãy buộc một sự cố kiểm thử để hoàn tất việc thiết lập Crashlytics và xem dữ liệu ban đầu trong trang tổng quan Crashlytics của bảng điều khiển Firebase.

Lựa chọn: Tải biểu tượng lên cho các bản dựng không phải Gradle hoặc các thư viện gốc chưa bị loại bỏ không truy cập được

Lựa chọn này có thể hữu ích trong các trường hợp sau:

  • Nếu bạn sử dụng quy trình xây dựng không phải Gradle

  • Nếu thư viện gốc chưa bị loại bỏ được cung cấp cho bạn theo cách nào đó mà bạn không thể truy cập được trong các bản dựng Gradle

Tuỳ chọn này yêu cầu bạn chạy lệnh CLI Firebase khi tạo bản phát hành hoặc bất kỳ bản dựng nào mà bạn muốn xem dấu vết ngăn xếp được biểu tượng hoá trong bảng điều khiển Firebase.

  1. Hãy đảm bảo rằng bạn đã hoàn tất các nhiệm vụ ban đầu sau đây trong quy trình công việc chính ở trên trang này:

    1. Bật Crashlytics trong bảng điều khiển Firebase.

    2. Thêm SDK Crashlytics cho NDKtrình bổ trợ Gradle Crashlytics.

    Lưu ý rằng với tuỳ chọn này, bạn không cần thêm tiện ích firebaseCrashlytics hoặc thiết lập tính năng tự động tải biểu tượng lên vì bạn sẽ sử dụng CLI Firebase (các bước tiếp theo bên dưới) để tạo và tải tệp biểu tượng lên.

  2. Thiết lập môi trường và dự án để tải biểu tượng lên:

    1. Làm theo hướng dẫn để cài đặt CLI Firebase.

      Nếu bạn đã cài đặt CLI, hãy nhớ cập nhật lên phiên bản mới nhất.

    2. (chỉ dành cho các ứng dụng sử dụng Android API cấp 30 trở lên) Cập nhật mẫu AndroidManifest.xml của ứng dụng để tắt tính năng Gắn thẻ con trỏ:

      1. Đánh dấu vào hộp Android Player Settings > Publishing Settings > Build > Custom Main Manifest (Cài đặt trình phát Android > Cài đặt phát hành > Bản dựng > Tệp kê khai chính tuỳ chỉnh).

      2. Mở mẫu tệp kê khai tại Assets/Plugins/Android/AndroidManifest.xml.

      3. Thêm thuộc tính sau vào thẻ ứng dụng: <application android:allowNativeHeapPointerTagging="false" ... />

  3. Tạo dự án.

  4. Tải thông tin về biểu tượng lên.

    Sau khi bản dựng hoàn tất, hãy tạo một tệp biểu tượng tương thích với Crashlytics và tải tệp đó lên máy chủ Firebase bằng cách chạy lệnh CLI Firebase sau:

    firebase crashlytics:symbols:upload --app=FIREBASE_APP_ID PATH/TO/SYMBOLS
    • FIREBASE_APP_ID: Mã ứng dụng Firebase cho Android (không phải tên gói)
      Ví dụ về mã ứng dụng Firebase cho Android: 1:567383003300:android:17104a2ced0c9b9b

      Dưới đây là hai cách để tìm Mã ứng dụng Firebase:

      • Trong tệp google-services.json, Mã ứng dụng là giá trị mobilesdk_app_id; hoặc

      • Trong bảng điều khiển Firebase, hãy chuyển đến phần Cài đặt dự án. Di chuyển xuống thẻ Ứng dụng của bạn, sau đó nhấp vào Ứng dụng Firebase mà bạn muốn để tìm Mã ứng dụng của ứng dụng đó.

    • PATH/TO/SYMBOLS: Đường dẫn đến tệp biểu tượng do CLI tạo

      • Đã xuất sang một dự án Android Studio – PATH/TO/SYMBOLS có thể là bất kỳ thư mục nào. CLI Firebase sẽ tìm kiếm đệ quy thư mục đã chỉ định cho các thư viện gốc có đuôi .so.

      • Tạo tệp APK ngay trong Unity — PATH/TO/SYMBOLS là đường dẫn của tệp biểu tượng nén được tạo trong thư mục gốc của dự án khi bản dựng của bạn hoàn tất (ví dụ: myproject/myapp-1.0-v100.symbols.zip).

    Cờ Nội dung mô tả
    --generator=csym

    Sử dụng trình tạo tệp ký hiệu cSYM cũ thay vì trình tạo Breakpad mặc định

    Không nên sử dụng. Bạn nên sử dụng trình tạo tệp biểu tượng Breakpad mặc định.

    --generator=breakpad

    Sử dụng trình tạo tệp biểu tượng Breakpad

    Xin lưu ý rằng mặc định để tạo tệp biểu tượng là Breakpad. Chỉ sử dụng cờ này nếu bạn đã thêm symbolGenerator { csym() } vào cấu hình bản dựng và muốn ghi đè cờ đó để sử dụng Breakpad.

    --dry-run

    Tạo tệp biểu tượng nhưng không tải lên

    Cờ này sẽ hữu ích nếu bạn muốn kiểm tra nội dung của các tệp được gửi.

    --debug Cung cấp thêm thông tin gỡ lỗi
  5. Cuối cùng, hãy buộc một sự cố kiểm thử để hoàn tất việc thiết lập Crashlytics và xem dữ liệu ban đầu trong trang tổng quan Crashlytics của bảng điều khiển Firebase.

    Sau khi tạo ứng dụng trong quá trình buộc xảy ra sự cố, hãy nhớ chạy lệnh crashlytics:symbols:upload CLI Firebase để tải tệp biểu tượng lên.