CrashlyticsListener не вызывается

Я использую этот код для отслеживания сбоя приложения:

val core = CrashlyticsCore
                .Builder()
                .listener {
                    Log.d("***", "Crash happened")
                }
                .build()
        val crashlyticsKit = Crashlytics
                .Builder()
                .core(core)
                .build()
        // Initialize Fabric with the debug-location_inactive crashlytics.
        Fabric.with(context, crashlyticsKit)

Я тестирую это с throw NullPointerException() и с Crashlytics.getInstance().crash(). Ни один из них не вызывает слушателя. Когда приложение запускается снова, это в журналах:

I/CrashlyticsCore: Initializing Crashlytics 2.6.1.23
I/CrashlyticsInitProvider: CrashlyticsInitProvider initialization successful
D/FirebaseApp: com.google.firebase.crash.FirebaseCrash is not linked. Skipping initialization.
I/CrashlyticsCore: Crashlytics report upload complete: SOME-LETTERS-AND-NUMBERS

Что я делаю неправильно?

РЕДАКТИРОВАТЬ Я использовал код из Как показать диалог после сбоя с помощью Crashlytics? в качестве шаблона для себя, но кажется, что API немного изменился (в этом ответе он инстанцируется как класс, но теперь это слушатель, см. документы)

Возможный дубликат Как показать диалог после сбоя с помощью Crashlytics?

Martin Zeitler 04.03.2019 03:14

@MartinZeitler, пожалуйста, посмотрите мое редактирование, где я объясняю, почему ваше предложение недействительно для текущей версии API.

Nikita Khlebushkin 04.03.2019 06:48

см. CrashlyticsCore.Builder: docs.fabric.io/javadocs/crashlytics-core/2.6.2/com/crashlyti‌​cs/… ... единственное, что изменилось, это то, что Crashlytics.setListener() устарело и заменено на CrashlyticsCore.Builder.listener(com.crashlytics.android.cor‌​e.CrashlyticsListene‌​r). Log в любом случае не является экземпляром CrashlyticsListener.

Martin Zeitler 04.03.2019 14:44

@MartinZeitler Я имею в виду, что слушатель (com.crashlytics.android.core.CrashlyticsListener, см. предоставленные вами документы) является интерфейсом, и поэтому мой синтаксис правильный. Создание тех же строк кода докажет вам, что

Nikita Khlebushkin 05.03.2019 11:30

@NikitaKlebushkin Должно работать так, как написано выше! где вы называете код инициализации?

Ahmed Hegazy 12.03.2019 09:56

@AhmedHegazy в Application::onCreate() я вызываю вспомогательный метод initialize(application: Application), в котором делаю всю инициализацию библиотеки. Это идет ПОСЛЕ super.onCreate()

Nikita Khlebushkin 12.03.2019 10:44

У меня есть тот же код, написанный выше, и он работает, поэтому я настроен скептически. Может быть, вы вызываете строку инициализации Fabric в другом месте с помощью Fabric.with(context, Crashylitics())? У вас последняя версия библиотеки?

Ahmed Hegazy 12.03.2019 14:30

@AhmedHegazy Только там. Версия, которую я пробовал: 2.9.1, 2.9.3. Я понимаю ваш скептицизм. Этот код довольно прост и работал над чужими проектами, поэтому должно быть что-то еще, я просто не знаю, где это искать.

Nikita Khlebushkin 12.03.2019 15:21

У меня 2.9.9, не могли бы вы попробовать эту версию?

Ahmed Hegazy 12.03.2019 15:26

@AhmedHegazy Я пробовал 2.9.9, но безуспешно

Nikita Khlebushkin 13.03.2019 13:47
3
10
1 725
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

По умолчанию Firebase Crashlytics использует хак поставщика контента для автоматической инициализации (com.crashlytics.android.CrashlyticsInitProvider внедряется в объединенный AndroidManifest).

В соответствии с документация автоматическую инициализацию можно переопределить с помощью флага meta-data:

<manifest>
    <application>

        <meta-data
            android:name = "firebase_crashlytics_collection_enabled"
            android:value = "false" />

    </application>
</manifest>

Теперь вызов Fabric.with(context, crashlyticsKit) фактически инициализирует sdk и должен правильно запускать прослушиватель.

Это сработало! Единственная проблема заключается в том, что это останавливает отправку сбоев на сервер?

Nikita Khlebushkin 13.03.2019 13:55

Пока вы не продолжите инициализировать Fabric.with(context себя, это будет работать. Вы можете проверить, запустив Crashlytics.getInstance().crash() сбой, который должен отображаться в веб-консоли.

Sergii Pechenizkyi 13.03.2019 14:01

В соответствии с документом https://docs.fabric.io/javadocs/crashlytics/2.6.8/deprecated-list.html мы должны использовать CrashlyticsCore.Builder().listener.

В файле проекта gradle поместите ниже зависимость.

buildscript {
    ext.kotlin_version = '1.3.21'
    repositories {
        google()
        jcenter()
        //TODO for fabric crash
        maven {
            url 'https://maven.fabric.io/public'
        }

    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.5.0-alpha07'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        //TODO for fabric crash
        classpath 'com.google.gms:google-services:4.2.0'
        classpath 'io.fabric.tools:gradle:1.26.1'
        //TODO end
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()


    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

в файле app.gradle поместите ниже gradle в зависимость:

    //TODO fabric crash 
    implementation 'com.google.firebase:firebase-core:16.0.7'
    implementation 'com.crashlytics.sdk.android:crashlytics:2.9.9'
    //TODO end

В файле манифеста поместите этот тег метаданных под тегом приложения.

в MainActivity.Kt

package com.darshan.crahdemo

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.crashlytics.android.Crashlytics
import com.crashlytics.android.core.CrashlyticsCore
import io.fabric.sdk.android.Fabric
import kotlinx.android.synthetic.main.activity_main.tvCrash

class MainActivity : AppCompatActivity() {

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val core = CrashlyticsCore
      .Builder()
      .listener {
        Log.d("****************", "Crash happened")
      }
      .build()

    val crashlyticsKit = Crashlytics
      .Builder()
      .core(core)
      .build()

    Fabric.with(this, crashlyticsKit)

    tvCrash.text = "Crash!"
    tvCrash.setOnClickListener {
      Crashlytics.getInstance().crash() // Force a crash
    }

  }
}

У меня тестовый код работает отлично. Прилагаю скриншот логов.

Спасибо за ваш ответ! Прошу прощения, но чем это отличается от моего кода?

Nikita Khlebushkin 13.03.2019 13:58

Другие вопросы по теме