Cannot initialize Crashlytics NDK

妖精的绣舞 提交于 2019-12-24 16:03:29

问题


I got a problem in initalizing Crashlytics for Android. The Java part works correctly but i cannot make NDK part to work because crashlytics_init() return a null value;

My project/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 containing

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

main activity code

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    jniCrashlyticsInit();

    ...
}

and the native content of 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");
}

As you imagine, "CRASHLYTICS NULL" is logged and it cannot initialize all the stuff. I've put logs also inside crashlytics.h and it happens to fail on this line (returning a null value)

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

Since i got no further infos, i really don't know how to proceed. Ideas?

Some info more: I use Android studio 3.0.0, and the NDK libraries are compiled manually with the following command

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

**** Update November 20th ****

As suggested by Todd Burner, I switched from "compile" to "implementation" on build.gradle from

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

to

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

then i ran

./gradlew assemble --refresh-dependencies

Unfortunally, crashlytics_init() still returns NULL


回答1:


I struggled days with this same issue. In my case I would blame partly the not-so-very-thorough documentation in the Fabric website and partly the lack of my reading comprehension.

I cannot be sure if you experience just the same thing, but my problem was that I tried to load Crashlytics NDK twice.

If you do the initialization from java like this:

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

the native Crashlytics is automatically loaded and you don't need to initialize Crashlytics from C++. If you step into the decompiled Crashlytics .class files starting from CrashlyticsNdk.class you can see that JniNativeApi.class already calls System.loadLibrary("crashlytics").

In fact, if you still try to initialize Crashlytics from native side after that, the line

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

will return NULL because the library has been already loaded.

What confused me is that the Official Fabric documentation doesn't say with bright red flashing letters that if you call new CrashlyticsNdk() from Java, you shouldn't try to load native Crashlytics from C++. To be fair, the documentation does say the following: In the process of initialization via Fabric.with(), the NDK Kit uses System.loadLibrary to load libcrashlytics. But it's a single line right before the Native API explanation starts and is easily overlooked.



来源:https://stackoverflow.com/questions/47285017/cannot-initialize-crashlytics-ndk

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!