现象:
5.0以下机器报错:
Process: xxx, PID: 26100
java.lang.NoClassDefFoundError: com/woxiang/demo/Fly
一开始以为是运行中找不到这个类,实则不然,是调用Fly类的函数A时出异常导致,函数A调用了native函数,native函数调用了signal函数:
signal(SIGALRM, timersignalhandler);
那么为什么在5.0及以上没问题呢,google 之:
signal was an inline function until platform android-21, now it's not inline anymore.
When you use the ndk r10, android-21 is used by default but it's not fully retro-compatible with devices running former Android versions. In your case, signal can't be found on your device (but it would run properly on Lollipop).
When using the NDK, you should use the platform (APP_PLATFORM:=android-XX) that corresponds to your android:minSdkVersion.
So here you can set APP_PLATFORM:=android-15 inside Application.mk Makefile, and your lib will use the inline version of signal, so it will not look for its symbol at runtime.
from:https://stackoverflow.com/questions/28740315/android-ndk-getting-java-lang-unsatisfiedlinkerror-dlopen-failed-cannot-loca?rq=1
就是说signal函数在5.0以前是内联函数,但是5.0及以后不是了,而我编译so文件时是用gradle编译的,
android studio这个坑货,编译ndk时默认的APP_PLATFORM是compileSdkVersion。
所以修改下gradle文件,加入platformVersion,clean一遍,clean一遍,clean一遍,强调是因为我不clean编译报错,再编译so即可。
apply plugin: 'com.android.model.library'
model {
android {
ndk {
platformVersion "android-15"//platformVersion option is available from 0.8.0.
}
}
}
如果你用的gradle版本是以前的,设置APP_PLATFORM的方式可能不同,自行google之。
NoClassDefFoundError的其它可能
解决问题过程中,发现分dex也可能导致这种问题,可参考:
https://developer.android.com/studio/build/multidex.html#mdex-gradle