我正在尝试使用NDK在我的Android应用程序中加载libspotify。
我正在使用库libspotify ++和jlibspotify。一切似乎都已加载,但是当libspotify尝试加载库“ libspotify.so.12”时,它崩溃了
我无法在android中使用符号链接。
码:
public class Session {
static {
System.loadLibrary("spotify");
System.loadLibrary("jlibspotify");
}
}
日志:
05-29 17:27:22.559: D/dalvikvm(32606): threadid=1: still suspended after undo (sc=1 dc=1)
05-29 17:27:25.527: D/dalvikvm(32606): Trying to load lib /data/data/se.warting.spotify/lib/libspotify.so 0x41692100
05-29 17:27:25.535: D/dalvikvm(32606): Added shared lib /data/data/se.warting.spotify/lib/libspotify.so 0x41692100
05-29 17:27:25.535: D/dalvikvm(32606): No JNI_OnLoad found in /data/data/se.warting.spotify/lib/libspotify.so 0x41692100, skipping init
05-29 17:27:25.543: D/dalvikvm(32606): Trying to load lib /data/data/se.warting.spotify/lib/libjlibspotify.so 0x41692100
05-29 17:27:27.637: W/dalvikvm(32606): Exception Ljava/lang/UnsatisfiedLinkError; thrown while initializing Lse/sony/tunefeud/spotiwrap/Session;
05-29 17:27:28.824: D/AndroidRuntime(32606): Shutting down VM
05-29 17:27:28.824: W/dalvikvm(32606): threadid=1: thread exiting with uncaught exception (group=0x40a421f8)
05-29 17:27:28.855: E/AndroidRuntime(32606): FATAL EXCEPTION: main
05-29 17:27:28.855: E/AndroidRuntime(32606): java.lang.ExceptionInInitializerError
05-29 17:27:28.855: E/AndroidRuntime(32606): at se.warting.spotify.PocActivity.onCreate(PocActivity.java:18)
05-29 17:27:28.855: E/AndroidRuntime(32606): at android.app.Activity.performCreate(Activity.java:4465)
05-29 17:27:28.855: E/AndroidRuntime(32606): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
05-29 17:27:28.855: E/AndroidRuntime(32606): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
05-29 17:27:28.855: E/AndroidRuntime(32606): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
05-29 17:27:28.855: E/AndroidRuntime(32606): at android.app.ActivityThread.access$600(ActivityThread.java:123)
05-29 17:27:28.855: E/AndroidRuntime(32606): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
05-29 17:27:28.855: E/AndroidRuntime(32606): at android.os.Handler.dispatchMessage(Handler.java:99)
05-29 17:27:28.855: E/AndroidRuntime(32606): at android.os.Looper.loop(Looper.java:137)
05-29 17:27:28.855: E/AndroidRuntime(32606): at android.app.ActivityThread.main(ActivityThread.java:4424)
05-29 17:27:28.855: E/AndroidRuntime(32606): at java.lang.reflect.Method.invokeNative(Native Method)
05-29 17:27:28.855: E/AndroidRuntime(32606): at java.lang.reflect.Method.invoke(Method.java:511)
05-29 17:27:28.855: E/AndroidRuntime(32606): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
05-29 17:27:28.855: E/AndroidRuntime(32606): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
05-29 17:27:28.855: E/AndroidRuntime(32606): at dalvik.system.NativeStart.main(Native Method)
05-29 17:27:28.855: E/AndroidRuntime(32606): Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: link_image[1936]: 118 could not load needed library 'libspotify.so.12' for 'libjlibspotify.so' (load_library[1091]: Library 'libspotify.so.12' not found)
05-29 17:27:28.855: E/AndroidRuntime(32606): at java.lang.Runtime.loadLibrary(Runtime.java:370)
05-29 17:27:28.855: E/AndroidRuntime(32606): at java.lang.System.loadLibrary(System.java:535)
05-29 17:27:28.855: E/AndroidRuntime(32606): at se.warting.spotify.spotiwrap.Session.<clinit>(Session.java:6)
05-29 17:27:28.855: E/AndroidRuntime(32606): ... 15 more
这是我从objdump得到的:
$arm-linux-androideabi-objdump -p libs/armeabi/libjlibspotify.so | grep NEEDED
NEEDED libspotify.so.12
NEEDED libstdc++.so
NEEDED libm.so
NEEDED libc.so
NEEDED libdl.so
$arm-linux-androideabi-objdump -p libs/armeabi/libspotify.so | grep NEEDED
NEEDED libm.so
NEEDED libc.so
NEEDED libdl.so
有谁知道如何使它工作?
最佳答案
我将在这里介绍一下我的Java / JVM技能,然后尝试在Android / Dalvik上应用它们。System.loadLibrary()
期望将JNI库名称作为其参数。在这种情况下,libspotify不是(也永远不是)JNI库,但libjlibspotify似乎是。请注意第一个调用如何在日志中抱怨缺少的JNI_OnLoad
函数。这通常是一个很好的提示。但是System.loadLibrary()
会接受任何共享库,只要它可以找到它,这就是在这种情况下调用不会失败的原因。
JNI库的从属库由平台的内置共享库加载机制自动加载。在这种情况下,libjlibspotify依赖于libspotify.so.12
,因此,如果在加载程序的路径中有可用的此类文件,则应在每次加载libjlibspotify时由系统自动加载该文件。
因此,在这种情况下,正确的Java代码应为:
public class Session {
static {
System.loadLibrary("jlibspotify");
}
}
但是,如果在
System.loadLibrary()
调用中未找到依赖库,则该调用将失败,并显示UnsatisfiedLinkError
(请参阅有关丢失的依赖libspotify.so.12
文件的日志)。libspotify 12当前在存档中以
libspotify.so.12.1.45
形式提供(带有一些符号链接libspotify.so
和libspotify.so.12
指向该文件)。在这种情况下,我对libjlibspotify的构建方式一无所知,但如果在Android设置中符号链接不相关,则应该构建libjlibspotify以便从存档中加载libspotify.so.12.1.45
,否需要重命名。