1

我正在尝试使用 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 

有谁知道该怎么做才能让它工作?

4

3 回答 3

4

I'll just break out my Java/JVM skills here and try applying them on Android/Dalvik.

  1. System.loadLibrary() expects a JNI library name as its argument. In this case libspotify is not (and never is) a JNI library, but libjlibspotify seems to be. Note how the first call whines in the log about the missing JNI_OnLoad function. This is usually a good hint. System.loadLibrary() does however accept any shared library as long as it can find it, and that's why the call doesn't fail in this scenario.

  2. Dependent libraries of a JNI library are loaded automatically by the platform's built-in shared library loading mechanisms. In this case, libjlibspotify depends on libspotify.so.12, so if there is such a file available in the loader's path, then this should be loaded automatically by the system whenever libjlibspotify is loaded.

    Hence, the proper Java code in this case should be:

    public class Session {
        static {
            System.loadLibrary("jlibspotify");
        }
    }
    

    However, if the dependent library is not found as part of the System.loadLibrary() invocation, then that call will fail with an UnsatisfiedLinkError (see the log about the missing dependent libspotify.so.12 file).

  3. libspotify 12 currently ships in the archive as libspotify.so.12.1.45 (with some symlinks libspotify.so and libspotify.so.12 pointing to that file). I don't know anything about how libjlibspotify has been built in this scenario, but if it is the case that the symlinks aren't relevant in the Android setting, then libjlibspotify should instead be built to load libspotify.so.12.1.45 from the archive, no renaming needed.

于 2012-05-30T13:15:49.137 回答
1

看来您需要更改创建 libspotify 的构建过程以获得正确的名称。

最简单的方法是使用 Android NDK 构建系统 - 它会正确编译和链接库。

于 2012-05-30T07:02:19.127 回答
1

Mārtiņš 的回答是正确的,它应该使用 Android 的 NDK 构建系统构建。当无法控制库时,有一种解决方法:

Instead of loading the library with System.loadLibrary( "JLibSpotify" ); i manualy copied /data/data/se.warting.spotify/lib/libspotify.so to /data/data/se.warting.spotify/libspotify.so.12 And then loaded the library with:

System.load("/data/data/se.warting.spotify/libspotify.so.12");

After that i could load jlibspotify as normal:

System.loadLibrary("jlibspotify");
于 2012-05-30T07:43:32.757 回答