گزارش‌های خرابی Android NDK را دریافت کنید

اگر برنامه Android شما حاوی کتابخانه‌های بومی است، می‌توانید ردیابی پشته کامل و گزارش‌های خرابی دقیق را برای کد بومی خود از Firebase Crashlytics با چند به‌روزرسانی کوچک در پیکربندی ساخت برنامه‌تان فعال کنید.

این راهنما نحوه پیکربندی گزارش خرابی با Firebase Crashlytics SDK برای NDK را شرح می‌دهد.

اگر به دنبال نحوه شروع کار با Crashlytics در پروژه های یونیتی خود هستید، راهنمای شروع Unity را بررسی کنید.

قبل از شروع

  1. اگر قبلاً این کار را نکرده اید، Firebase را به پروژه اندروید خود اضافه کنید . اگر برنامه اندروید ندارید، می توانید یک برنامه نمونه دانلود کنید.

  2. توصیه می‌شود : برای دریافت خودکار گزارش‌های خرده نان برای درک اقدامات کاربر که منجر به خرابی، رویداد غیرمرگبار یا ANR می‌شود، باید Google Analytics در پروژه Firebase خود فعال کنید.

    • اگر پروژه Firebase موجود شما Google Analytics فعال نکرده است، می توانید Google Analytics از برگه Integrations فعال کنید. > تنظیمات پروژه در کنسول Firebase .

    • اگر در حال ایجاد یک پروژه Firebase هستید، Google Analytics در جریان کار ایجاد پروژه فعال کنید.

  3. مطمئن شوید که برنامه شما حداقل نسخه های مورد نیاز زیر را دارد:

    • Gradle 8.0
    • پلاگین اندروید Gradle 8.1.0
    • خدمات گوگل پلاگین Gradle 4.4.1

مرحله ۱ : Crashlytics SDK for NDK را به برنامه خود اضافه کنید

در فایل Gradle ماژول (سطح برنامه) خود (معمولا <project>/<app-module>/build.gradle.kts یا <project>/<app-module>/build.gradle )، وابستگی را برای کتابخانه Crashlytics NDK برای Android اضافه کنید. توصیه می‌کنیم از Firebase Android BoM برای کنترل نسخه‌سازی کتابخانه استفاده کنید.

برای تجربه بهینه با Crashlytics ، توصیه می‌کنیم Google Analytics در پروژه Firebase خود فعال کنید و Firebase SDK برای Google Analytics را به برنامه خود اضافه کنید.

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

با استفاده از Firebase Android BoM ، برنامه شما همیشه از نسخه‌های سازگار کتابخانه‌های Firebase Android استفاده می‌کند.

اگر تصمیم گرفتید از Firebase BoM استفاده نکنید، باید هر نسخه کتابخانه Firebase را در خط وابستگی آن مشخص کنید.

توجه داشته باشید که اگر از چندین کتابخانه 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.4.0")
    implementation("com.google.firebase:firebase-analytics:22.2.0")
}
به دنبال یک ماژول کتابخانه خاص کاتلین هستید؟ از اکتبر 2023 ( Firebase BoM 32.5.0) ، توسعه دهندگان Kotlin و Java می توانند به ماژول کتابخانه اصلی وابسته باشند (برای جزئیات، به سؤالات متداول در مورد این ابتکار مراجعه کنید).

مرحله 2 : افزونه Crashlytics Gradle را به برنامه خود اضافه کنید

  1. در فایل Gradle در سطح ریشه (سطح پروژه) خود ( <project>/build.gradle.kts یا <project>/build.gradle )، افزونه Crashlytics Gradle را به بلوک plugins اضافه کنید:

    KotlinGroovy
    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. در فایل Gradle ماژول (سطح برنامه) خود (معمولا <project>/<app-module>/build.gradle.kts یا <project>/<app-module>/build.gradle )، افزونه Crashlytics Gradle را اضافه کنید:

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

مرحله 3 : افزونه Crashlytics را به بیلد خود اضافه کنید

در فایل Gradle ماژول (سطح برنامه) خود (معمولا <project>/<app-module>/build.gradle.kts یا <project>/<app-module>/build.gradle )، پسوند Crashlytics را پیکربندی کنید.

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

مرحله 4 : بارگذاری خودکار نمادهای بومی را تنظیم کنید

برای ایجاد ردیابی پشته قابل خواندن از خرابی های NDK، Crashlytics باید درباره نمادهای موجود در باینری های بومی شما بداند. افزونه Crashlytics Gradle شامل کار uploadCrashlyticsSymbolFile BUILD_VARIANT برای خودکارسازی این فرآیند است.

  1. برای اینکه بتوانید به وظیفه آپلود خودکار نمادها دسترسی داشته باشید، مطمئن شوید که nativeSymbolUploadEnabled در فایل Gradle ماژول (سطح برنامه) روی true تنظیم شده باشد.

  2. برای اینکه نام روش‌ها در ردیابی پشته شما ظاهر شود، باید صراحتاً وظیفه uploadCrashlyticsSymbolFile BUILD_VARIANT پس از هر ساخت کتابخانه NDK خود فراخوانی کنید. به عنوان مثال:

    >./gradlew app:assembleBUILD_VARIANT\
               app:uploadCrashlyticsSymbolFileBUILD_VARIANT
  3. هم Crashlytics SDK برای NDK و هم پلاگین Crashlytics Gradle به وجود شناسه ساخت گنو در اشیاء مشترک بومی بستگی دارد.

    با اجرا کردن می توانید وجود این شناسه را تأیید کنید readelf -n در هر دودویی. اگر شناسه ساخت وجود ندارد، اضافه کنید -Wl,--build-id به پرچم‌های سیستم ساخت شما برای رفع مشکل.

مرحله 5 : یک خرابی آزمایشی را مجبور کنید تا راه‌اندازی تمام شود

برای تکمیل راه‌اندازی Crashlytics و مشاهده داده‌های اولیه در داشبورد Crashlytics کنسول Firebase ، باید یک خرابی آزمایشی را اجباری کنید.

  1. کدی را به برنامه خود اضافه کنید که می توانید از آن برای اجبار تست خرابی استفاده کنید.

    می توانید از کد زیر در MainActivity برنامه خود استفاده کنید تا دکمه ای را به برنامه خود اضافه کنید که با فشار دادن آن باعث خرابی می شود. این دکمه دارای برچسب "تست تصادف" است.

    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. اپلیکیشن خود را بسازید و اجرا کنید.

  3. برای ارسال اولین گزارش خرابی برنامه خود، خرابی آزمایشی را اجباری کنید:

    1. برنامه خود را از دستگاه آزمایشی یا شبیه ساز خود باز کنید.

    2. در برنامه خود، دکمه «Test Crash» را که با استفاده از کد بالا اضافه کردید، فشار دهید.

    3. پس از خراب شدن برنامه، آن را مجددا راه اندازی کنید تا برنامه شما بتواند گزارش خرابی را به Firebase ارسال کند.

  4. برای مشاهده خرابی آزمایشی خود، به داشبورد Crashlytics کنسول Firebase بروید.

    اگر کنسول را به‌روزرسانی کرده‌اید و بعد از پنج دقیقه هنوز خرابی آزمایشی را نمی‌بینید، ثبت اشکال‌زدایی را فعال کنید تا ببینید آیا برنامه شما گزارش‌های خرابی را ارسال می‌کند یا خیر.


و بس! Crashlytics اکنون برنامه شما را برای خرابی ها زیر نظر دارد و می توانید گزارش ها و آمار خرابی ها را در داشبورد Crashlytics مشاهده و بررسی کنید.

مراحل بعدی

عیب یابی

اگر در کنسول Firebase و در logcat ردیابی پشته های مختلف مشاهده می کنید، به راهنمای عیب یابی مراجعه کنید.



گزینه های جایگزین برای بارگذاری نمادها

گردش کار اصلی در این صفحه بالا برای ساخت‌های استاندارد Gradle قابل اجرا است. با این حال، برخی از برنامه‌ها از پیکربندی یا ابزار متفاوتی استفاده می‌کنند (مثلاً یک فرآیند ساخت غیر از Gradle). در این شرایط، گزینه‌های زیر ممکن است برای بارگذاری موفقیت‌آمیز نمادها مفید باشند.

گزینه : نمادها را برای ماژول های کتابخانه و وابستگی های خارجی بارگذاری کنید

این گزینه می تواند در شرایط زیر مفید باشد:

  • اگر از یک فرآیند ساخت NDK سفارشی شده در Gradle استفاده می کنید
  • اگر کتابخانه‌های بومی شما در یک ماژول کتابخانه/ویژگی ساخته شده‌اند یا توسط شخص ثالث ارائه شده‌اند
  • اگر کار آپلود خودکار نماد ناموفق باشد یا خرابی های غیر نمادین را در داشبورد مشاهده کنید

وظیفه آپلود نماد Crashlytics استاندارد فرض می‌کند که شما کتابخانه‌های بومی خود را به عنوان بخشی از ساخت Gradle ماژول برنامه خود، با استفاده از ابزارهای استاندارد ساخت NDK مانند CMake می‌سازید.

با این حال، اگر از یک فرآیند ساخت NDK سفارشی شده در Gradle استفاده می‌کنید، یا کتابخانه‌های بومی شما در یک ماژول کتابخانه/ویژگی ساخته شده‌اند یا توسط یک شخص ثالث ارائه شده‌اند، ممکن است لازم باشد مسیر کتابخانه‌های بدون لایه خود را به صراحت مشخص کنید. برای انجام این کار، می توانید ویژگی unstrippedNativeLibsDir را در پسوند Crashlytics در فایل ساخت Gradle خود اضافه کنید.

  1. اطمینان حاصل کنید که وظایف اولیه زیر را از گردش کار اصلی قبلاً در این صفحه تکمیل کرده اید:

    1. Crashlytics در کنسول Firebase فعال شد.

    2. Crashlytics SDK برای NDK و پلاگین Crashlytics Gradle اضافه شد.

    3. افزونه Crashlytics را به ساخت شما اضافه کرد.

    4. بارگذاری خودکار نمادهای بومی را تنظیم کنید.

  2. برای اینکه وظیفه آپلود خودکار نماد بتواند اطلاعات نماد شما را پیدا کند، موارد زیر را به فایل Gradle ماژول (سطح برنامه) خود اضافه کنید (معمولا <project>/<app-module>/build.gradle.kts یا <project>/<app-module>/build.gradle ):

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

    افزونه Crashlytics به صورت بازگشتی دایرکتوری مشخص شده را برای کتابخانه های بومی با پسوند .so جستجو می کند. سپس Crashlytics نمادهای اشکال زدایی را از تمام این کتابخانه ها استخراج می کند و آنها را در سرورهای Firebase آپلود می کند.

    در اینجا چیزی است که می توانید در ویژگی unstrippedNativeLibsDir مشخص کنید:

    • هر آرگومان مجاز برای org.gradle.api.Project#files(Object...) از جمله: java.lang.String java.io.File یا org.gradle.api.file.FileCollection

    • دایرکتوری های متعدد برای یک طعم ساخت با ارائه یک لیست یا نمونه FileCollection

    • (شروع با پلاگین Crashlytics Gradle نسخه 3.0.0) دایرکتوری های متعدد را در محصولات جداگانه جمع آوری کنید و طعم ها را بسازید.

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

    وظیفه uploadCrashlyticsSymbolFilesBasicRelease فقط نمادها را در MY/NATIVE/LIBS آپلود می کند، اما uploadCrashlyticsSymbolFilesFeatureXRelease نمادها را در MY/NATIVE/LIBS و MY/FEATURE_X/LIBS آپلود می کند.

  3. در نهایت، برای پایان راه‌اندازی Crashlytics و مشاهده داده‌های اولیه در داشبورد Crashlytics کنسول Firebase ، یک خرابی آزمایشی را مجبور کنید .

گزینه : بارگذاری نمادها برای ساخت‌های غیر Gradle یا کتابخانه‌های بومی غیرقابل دسترس

این گزینه می تواند در شرایط زیر مفید باشد:

  • اگر از یک فرآیند ساخت غیر از Gradle استفاده می کنید

  • اگر کتابخانه‌های بومی غیرمستقیم شما به گونه‌ای در اختیار شما قرار می‌گیرد که در طول ساخت‌های Gradle در دسترس نیستند.

این گزینه مستلزم آن است که هنگام ایجاد نسخه انتشار یا هر بیلدی که می‌خواهید ردپای پشته نمادین آن را در کنسول Firebase ببینید، یک فرمان Firebase CLI را اجرا کنید.

  1. اطمینان حاصل کنید که وظایف اولیه زیر را از گردش کار اصلی قبلاً در این صفحه تکمیل کرده اید:

    1. Crashlytics در کنسول Firebase فعال شد.

    2. Crashlytics SDK برای NDK و پلاگین Crashlytics Gradle اضافه شد.

    توجه داشته باشید که با استفاده از این گزینه، نیازی به افزودن پسوند firebaseCrashlytics یا تنظیم آپلود خودکار نماد ندارید زیرا در عوض از Firebase CLI (مراحل بعدی زیر) برای تولید و آپلود فایل‌های نماد خود استفاده خواهید کرد.

  2. محیط و پروژه خود را برای بارگذاری نماد تنظیم کنید:

    1. دستورالعمل ها را برای نصب Firebase CLI دنبال کنید.

      اگر قبلاً CLI را نصب کرده‌اید، حتماً به آخرین نسخه آن به‌روزرسانی کنید .

    2. (فقط برای برنامه‌هایی که از Android API سطح 30 و بالاتر استفاده می‌کنند) الگوی AndroidManifest.xml برنامه خود را برای غیرفعال کردن Pointer Tagging به‌روزرسانی کنید:

      1. کادر تنظیمات Player Android > Publishing Settings > Build > Custom Main Manifest را علامت بزنید.

      2. الگوی مانیفست واقع در Assets/Plugins/Android/AndroidManifest.xml را باز کنید.

      3. ویژگی زیر را به تگ برنامه اضافه کنید: <application android:allowNativeHeapPointerTagging="false" ... />

  3. پروژه خود را بسازید

  4. اطلاعات نمادهای خود را آپلود کنید.

    پس از اتمام ساخت، یک فایل نماد سازگار Crashlytics ایجاد کنید و با اجرای دستور Firebase CLI زیر آن را در سرورهای Firebase آپلود کنید:

    firebase crashlytics:symbols:upload --app=FIREBASE_APP_ID PATH/TO/SYMBOLS
    • FIREBASE_APP_ID : شناسه برنامه Android Firebase شما (نه نام بسته شما)
      ID برنامه اندروید Firebase مثال: 1:567383003300:android:17104a2ced0c9b9b

      در اینجا دو روش برای یافتن شناسه برنامه Firebase وجود دارد:

      • در فایل google-services.json ، شناسه برنامه شما مقدار mobilesdk_app_id است. یا

      • در کنسول Firebase ، به تنظیمات پروژه خود بروید. به سمت پایین به کارت برنامه های شما بروید، سپس روی برنامه Firebase مورد نظر کلیک کنید تا شناسه برنامه آن را پیدا کنید.

    • PATH/TO/SYMBOLS : مسیر فایل نماد تولید شده توسط CLI

      • به یک پروژه Android Studio صادر می شود - PATH/TO/SYMBOLS می تواند هر دایرکتوری باشد. Firebase CLI به صورت بازگشتی دایرکتوری مشخص شده را برای کتابخانه های بومی با پسوند .so جستجو می کند.

      • APK را مستقیماً از داخل Unity ساخته شده است - PATH/TO/SYMBOLS مسیر فایل نماد زیپ شده است که پس از اتمام ساخت شما در دایرکتوری ریشه پروژه ایجاد می شود (به عنوان مثال: myproject/myapp-1.0-v100.symbols.zip ).

    پرچم توضیحات
    --generator=csym

    از تولیدکننده فایل نماد cSYM قدیمی به جای تولیدکننده پیش‌فرض Breakpad استفاده می‌کند

    برای استفاده توصیه نمی شود. توصیه می کنیم از تولید کننده فایل نماد Breakpad پیش فرض استفاده کنید.

    --generator=breakpad

    از تولید کننده فایل نماد Breakpad استفاده می کند

    توجه داشته باشید که پیش فرض برای تولید فایل نماد، Breakpad است. فقط در صورتی از این پرچم استفاده کنید که اضافه کرده اید symbolGenerator { csym() } در پیکربندی ساخت شماست و می‌خواهید آن را نادیده بگیرید تا به جای آن از Breakpad استفاده کنید.

    --dry-run

    فایل های نماد را تولید می کند اما آنها را آپلود نمی کند

    اگر می خواهید محتوای فایل های ارسال شده را بررسی کنید، این پرچم مفید است.

    --debug اطلاعات رفع اشکال اضافی را ارائه می دهد
  5. در نهایت، برای پایان راه‌اندازی Crashlytics و مشاهده داده‌های اولیه در داشبورد Crashlytics کنسول Firebase ، یک خرابی آزمایشی را مجبور کنید .

    بعد از اینکه برنامه خود را به عنوان بخشی از خرابی اجباری ساختید، مطمئن شوید که فرمان Firebase CLI crashlytics:symbols:upload برای آپلود فایل نماد خود اجرا کنید.