开发者

Mixing Android External JAR and JNI gone wild

开发者 https://www.devze.com 2023-01-24 22:54 出处:网络
A short history. please bear with me :) I have an Android project that uses JNI which works very good.

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 c开发者_运维技巧orrectly 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


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


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) 
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号