混合 Android 外部 JAR 和 JNI 变得疯狂

发布于 2024-10-01 13:04:38 字数 3446 浏览 0 评论 0原文

简短的历史。请耐心等待:)

我有一个使用 JNI 的 Android 项目,它运行得很好。

我决定从这个 jni 项目的源代码中创建一个外部 jar (用于分发)

为了创建这个 jar,我听取了其他人的建议并创建了一个新的 Java 项目,其中包含我需要的几个 jni 类存放在罐子里。我已将此 java 项目导出到一个 jar (不是作为可运行的 jar),

我创建了一个新的 Android 项目,在其中尝试使用有问题的 jar 文件。

在我玩完这个新的 android 项目后,我开始意识到应与 jni 类一起使用的 .so 文件不能驻留在 jar 文件本身内(Eclipse 抱怨它......)所以我创建了一个 lib 目录在保存 .so 文件的新 Android 项目中。

当我运行这个新的 Android 项目时,我无法使用任何具有本机方法的类,并且我只能使用那些纯 java 实现的类。

当尝试创建基于 jni 的对象之一的实例时,我不断收到“ExceptionInInitializerError”。

更新: 看来错误来自于尝试加载 jni 库,

System.loadLibrary("lib-jni");

这是 logcat:

> ERROR/SightEngine(2479): About to load the lib-jni.so
ERROR/SightExample(2479): WARNING: Could not init SightEngine java.lang.ExceptionInInitializerError
ERROR/AndroidRuntime(2479): Uncaught handler: thread main exiting due to uncaught exception
ERROR/AndroidRuntime(2479): java.lang.RuntimeException: Unable to start activity ComponentInfo{eyesight.android.example/eyesight.android.example.SightExample}: java.lang.NullPointerException: println needs a message
ERROR/AndroidRuntime(2479):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496)
ERROR/AndroidRuntime(2479):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
ERROR/AndroidRuntime(2479):     at android.app.ActivityThread.access$2200(ActivityThread.java:119)
ERROR/AndroidRuntime(2479):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
ERROR/AndroidRuntime(2479):     at android.os.Handler.dispatchMessage(Handler.java:99)
ERROR/AndroidRuntime(2479):     at android.os.Looper.loop(Looper.java:123)
ERROR/AndroidRuntime(2479):     at android.app.ActivityThread.main(ActivityThread.java:4363)
ERROR/AndroidRuntime(2479):     at java.lang.reflect.Method.invokeNative(Native Method)
ERROR/AndroidRuntime(2479):     at java.lang.reflect.Method.invoke(Method.java:521)
ERROR/AndroidRuntime(2479):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
ERROR/AndroidRuntime(2479):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
ERROR/AndroidRuntime(2479):     at dalvik.system.NativeStart.main(Native Method)
ERROR/AndroidRuntime(2479): Caused by: java.lang.NullPointerException: println needs a message
ERROR/AndroidRuntime(2479):     at android.util.Log.println(Native Method)
ERROR/AndroidRuntime(2479):     at android.util.Log.e(Log.java:208)
ERROR/AndroidRuntime(2479):     at eyesight.android.example.SightExample.onCreate(SightExample.java:28)
ERROR/AndroidRuntime(2479):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
ERROR/AndroidRuntime(2479):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
ERROR/AndroidRuntime(2479):     ... 11 more
ERROR/dalvikvm(2479): Unable to open stack trace file '/data/anr/traces.txt': Permission denied

一些提示:

  • 我可以在 .apk 文件中看到 .so 文件。
  • 我尝试在 JNI Android.mk 中定义外部 jar 文件,但没有发生任何令人兴奋的事情。这是我使用的行(编译没有问题..)

    LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := libtestjar:lib/testJar.jar include $(BUILD_MULTI_PREBUILT)

  • 我能够使用仅存在于 jar 文件中的常规 java 类。 (我知道我在重复自己......:))这意味着我已经在项目中正确定义了这个jar。

    • 包含基于 jni 的类的 java 项目引用了 android.jar(sdk 级别 7)

有没有人对如何完成此任务有任何建议?我觉得我已经快到了...

谢谢您的时间和努力:)

Itamar

A short history. please bear with me :)

I have an Android project that uses JNI which works very good.

I've decided to create out of the source of this jni project an external jar (for distribution)

In order to create this jar I've taken the advice of others and created a new Java project that holds the few jni classes I need to store in the jar. I've exported this java project to a jar (not as a runnable jar)

I've created a new Android Project in which I try to use the jar file in question.

After I've played with this new android project I came to realize that the .so file which should accompany the jni classes can't reside inside the jar file itself (Eclipse complained about it..) So I've created a lib directory inside the new Android Project which holds the .so file.

When I run this new Android project I can't work with any of the classes which has native methods, And I can only work with those classes which are pure java implementation.

I keep getting "ExceptionInInitializerError" when trying to create an instance of one of jni based objects.

Update:
It seems that the error comes from trying to load the jni library in line

System.loadLibrary("lib-jni");

Here is the logcat:

> ERROR/SightEngine(2479): About to load the lib-jni.so
ERROR/SightExample(2479): WARNING: Could not init SightEngine java.lang.ExceptionInInitializerError
ERROR/AndroidRuntime(2479): Uncaught handler: thread main exiting due to uncaught exception
ERROR/AndroidRuntime(2479): java.lang.RuntimeException: Unable to start activity ComponentInfo{eyesight.android.example/eyesight.android.example.SightExample}: java.lang.NullPointerException: println needs a message
ERROR/AndroidRuntime(2479):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496)
ERROR/AndroidRuntime(2479):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
ERROR/AndroidRuntime(2479):     at android.app.ActivityThread.access$2200(ActivityThread.java:119)
ERROR/AndroidRuntime(2479):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
ERROR/AndroidRuntime(2479):     at android.os.Handler.dispatchMessage(Handler.java:99)
ERROR/AndroidRuntime(2479):     at android.os.Looper.loop(Looper.java:123)
ERROR/AndroidRuntime(2479):     at android.app.ActivityThread.main(ActivityThread.java:4363)
ERROR/AndroidRuntime(2479):     at java.lang.reflect.Method.invokeNative(Native Method)
ERROR/AndroidRuntime(2479):     at java.lang.reflect.Method.invoke(Method.java:521)
ERROR/AndroidRuntime(2479):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
ERROR/AndroidRuntime(2479):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
ERROR/AndroidRuntime(2479):     at dalvik.system.NativeStart.main(Native Method)
ERROR/AndroidRuntime(2479): Caused by: java.lang.NullPointerException: println needs a message
ERROR/AndroidRuntime(2479):     at android.util.Log.println(Native Method)
ERROR/AndroidRuntime(2479):     at android.util.Log.e(Log.java:208)
ERROR/AndroidRuntime(2479):     at eyesight.android.example.SightExample.onCreate(SightExample.java:28)
ERROR/AndroidRuntime(2479):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
ERROR/AndroidRuntime(2479):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
ERROR/AndroidRuntime(2479):     ... 11 more
ERROR/dalvikvm(2479): Unable to open stack trace file '/data/anr/traces.txt': Permission denied

A few pointers:

  • I can see the .so file inside the .apk file.
  • I've tried defining the external jar file in the JNI Android.mk but nothing exciting happened. here are the lines I used (it compiled without a problem..)

    LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := libtestjar:lib/testJar.jar
    include $(BUILD_MULTI_PREBUILT)

  • I'm able to work with regular java classes that exist only in jar file. (I know I'm repeating myself.. :) ) which means I've correctly defined this jar in the project.

    • The java project that holds the jni based classes has a reference to the android.jar (sdk level 7)

Does anyone has any suggestions has to how this task can be accomplished? I feel like I'm almost there...

Thank you for your time and effort :)

Itamar

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

七七 2024-10-08 13:04:38

在 android 项目中,您是否将 .so 文件放在 lib/armeabi 下?

顺便说一句,我有与你相同的设置(构建 jar 的 java 项目和使用该 jar 的 android 项目)。

我设法将 .so 文件打包到 jar 中...这就是我所做的:

- 在构建库 JAR 时,我将 .so 文件压缩到一个文件中(比如armeabi.zip)并将其放入“assets”文件夹中在罐子里。

- 构建 Android 项目时,armeabi.zip 将位于 apk 内的“assets”文件夹中。

-在运行时(第一次启动)我将armeabi.zip的内容从资产中提取到“/data/data/”+ context.getPackageName()中。

-最后使用 System.load(/data/data//libfilename.so) 加载提取的 .so 库

希望这会有所帮助。

法迪

In the android project, did you put your .so files under lib/armeabi ?

by the way, i have the same setup as you (java project that builds a jar and an android project that uses the jar).

I managed to package the .so files in the jar ... here's what I did:

-when building the library JAR, I zip the .so files into a file (say armeabi.zip) and put it inside an 'assets' folder in the jar.

-when building the android project, the armeabi.zip will be in the 'assets' folder inside your apk.

-at runtime (first start) I extract the contents of armeabi.zip from the assets into "/data/data/" + context.getPackageName().

-finally load the extracted .so libs using System.load(/data/data//libfilename.so)

hope this helps.

Fadi

八巷 2024-10-08 13:04:38

看起来错误日志调用缺少一条消息。

ERROR/AndroidRuntime(2479): Caused by: java.lang.NullPointerException: println needs a message
ERROR/AndroidRuntime(2479): at android.util.Log.println(Native Method)
ERROR/AndroidRuntime(2479): at android.util.Log.e(Log.java:208)
ERROR/AndroidRuntime(2479): at eyesight.android.example.SightExample.onCreate(SightExample.java:28) 

Looks like an error log call is missing a message.

ERROR/AndroidRuntime(2479): Caused by: java.lang.NullPointerException: println needs a message
ERROR/AndroidRuntime(2479): at android.util.Log.println(Native Method)
ERROR/AndroidRuntime(2479): at android.util.Log.e(Log.java:208)
ERROR/AndroidRuntime(2479): at eyesight.android.example.SightExample.onCreate(SightExample.java:28) 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文