【问题标题】:Cannot initialize Crashlytics NDK无法初始化 Crashlytics NDK
【发布时间】:2017-11-14 11:46:38
【问题描述】:

我在为 Android 初始化 Crashlytics 时遇到问题。 Java 部分工作正常,但我无法使 NDK 部分工作,因为 crashlytics_init() 返回空值;

我的项目/build.gradle

buildscript {
    repositories {
        jcenter()
        google()
        maven {
            url 'https://maven.fabric.io/public'
        }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.0'
        classpath 'io.fabric.tools:gradle:1.24.4'
        classpath 'com.google.gms:google-services:3.1.0'
    }
}

allprojects {
    repositories {
        jcenter()
        google()

        maven {
            url 'https://maven.fabric.io/public'
        }

    }
}

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

app/build.gradle 包含

compileSdkVersion 26

android {

    defaultConfig {
        ...
        minSdkVersion 19
        targetSdkVersion 22
        ...
    }

    ...
}

crashlytics {
    enableNdk true
    manifestPath 'C:\\full\\path\\to\\manifest\\AndroidManifest.xml'
}

dependencies {
    implementation 'com.google.firebase:firebase-crash:11.6.0'
    compile fileTree(include: ['*.jar'], dir: 'libs')

    compile('com.crashlytics.sdk.android:crashlytics:2.7.1@aar') {
        transitive = true
    }
    compile('com.crashlytics.sdk.android:crashlytics-ndk:1.1.6@aar') {
        transitive = true;
    }

    compile 'com.google.firebase:firebase-core:11.6.0'

    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:26.1.0'
    compile 'com.android.support:support-v4:26.1.0'
    compile 'org.apache.commons:commons-compress:1.12'
    compile 'org.tukaani:xz:1.5'
}

主要活动代码

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    jniCrashlyticsInit();

    ...
}

以及 jniCrashlyticsInit() 的原生内容

void Java_com_my_app_MainActivity_jniCrashlyticsInit(JNIEnv *env,
                                                     jobject thiz)
{
    crashlytics = crashlytics_init();

    if (crashlytics == NULL)
        log("CRASHLYTICS NULL");
    else
        log("CRASHLYTICS NON NULL");
}

正如您想象的那样,“CRASHLYTICS NULL”已被记录,它无法初始化所有内容。 我也将日志放在crashlytics.h 中,它恰好在这一行失败(返回空值)

__crashlytics_unspecified_t* ctx = ((__crashlytics_initialize_t) sym_ini)();

由于我没有进一步的信息,我真的不知道如何进行。 想法?

更多信息: 我用的是Android studio 3.0.0,NDK库是用下面的命令手动编译的

/cygdrive/c/Android/ndk-r15c/ndk-build.cmd NDK_DEBUG=0 APP_BUILD_SCRIPT=./Android.mk NDK_PROJECT_PATH=. APP_PLATFORM=android-19    

**** 11 月 20 日更新 ****

按照 Todd Burner 的建议,我在 build.gradle 上从 "compile" 切换到 "implementation" 来自

compile('com.crashlytics.sdk.android:crashlytics:2.7.1@aar') {
    transitive = true
}
compile('com.crashlytics.sdk.android:crashlytics-ndk:1.1.6@aar') {
    transitive = true;
}

implementation('com.crashlytics.sdk.android:crashlytics:2.7.1@aar') {
    transitive = true
}
implementation('com.crashlytics.sdk.android:crashlytics-ndk:1.1.6@aar') {
    transitive = true;
}

然后我跑了

./gradlew assemble --refresh-dependencies

不幸的是,crashlytics_init() 仍然返回 NULL

【问题讨论】:

  • 感谢您与我们联系。我们还没有正式支持 AS 3,这可以解释这一点。如果您在 AS 2.x.x 中遇到任何问题,能否告诉我。这个项目是迁移了还是在 AS 3 中设置为新项目?谢谢!
  • 感谢您的回复!项目已经 2 岁了,我上周搬到了 AS 3,但我昨天第一次尝试使用 Crashlytics。因此我不知道它是否适用于 AS 2。抱歉:(顺便说一句,java 崩溃已被完美检测和收集。
  • 您可以尝试将编译切换到实现并运行 ./gradlew assemble --refresh-dependencies 谢谢!
  • Burner 先生,我按照您的建议做了(请检查更新后的问题)。不走运 X(
  • 也许您忘记在 Java 端初始化 CrashlyticsNdk?在这里看到它,它帮助了我:stackoverflow.com/questions/47211657/… P.S. Crashlytics NDK 文档很糟糕:它缺少大量信息和示例...

标签: crashlytics crashlytics-android


【解决方案1】:

我在同样的问题上苦苦挣扎了好几天。就我而言,我会部分归咎于 Fabric 网站上的文档不够详尽,部分原因是我缺乏阅读理解能力。

我不确定您是否遇到同样的事情,但我的问题是我尝试加载 Crashlytics NDK 两次。

如果你像这样从 java 进行初始化:

Fabric.with(this, new Crashlytics(), new CrashlyticsNdk()); 

本机 Crashlytics 会自动加载,您无需从 C++ 初始化 Crashlytics。如果您从 CrashlyticsNdk.class 开始进入反编译的 Crashlytics .class 文件,您可以看到 JniNativeApi.class 已经调用了 System.loadLibrary("crashlytics")

事实上,如果你在那之后仍然尝试从本机端初始化 Crashlytics,行

__crashlytics_unspecified_t* ctx = ((__crashlytics_initialize_t) sym_ini)();

将返回 NULL,因为该库已加载。

让我感到困惑的是,Official Fabric documentation 并没有用亮红色闪烁的字母表示如果你从 Java 调用 new CrashlyticsNdk(),你不应该尝试从 C++ 加载本机 Crashlytics。公平地说,文档确实说了以下内容:在通过 Fabric.with() 进行初始化的过程中,NDK Kit 使用 System.loadLibrary 来加载 libcrashlytics。 但它是在 Native 之前的一行API 解释开始,很容易被忽略。

【讨论】:

  • 我试过了,sym_ini 仍然返回 NULL。文档说当 crashlytics_init 被调用时,库已经被 new CrashlyticsNdk() 加载了。我认为这就是它应该如何工作的方式。
  • 如果 sym_ini 返回 NULL,那么您并没有真正尝试过,因为我的解决方案是根本不调用 crashlytics_init()。只需使用 new CrashlyticsNdk() 从 java 端加载库,在 C++ 端什么都不做。然后在 C++ 端导致测试崩溃。至少在我的项目中,我可以在 Fabric 中看到本机故障转储。
  • 我的目标是能够在 C 崩溃报告中注释附加信息。文档指出,这可以通过 crashlytics_context_t::log 方法实现,但您需要一个 crashlytics 上下文才能调用它。除非我调用 crashlytics_init(),否则我无法获得 crashlytics 上下文。
猜你喜欢
  • 1970-01-01
  • 2021-05-08
  • 2019-09-25
  • 2014-04-23
  • 2015-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多