I need to create an Android library which I can include as a jar in any Android application. I use NetBeans 6.8, the nbandroid plugin, and the Android SDK.
The steps I took so far are:
1) Create the library project, with android.jar included to have access to Android classes (the library uses android.util.Log and other Android classes).
2) Compile the library as a jar.
3) Add the library's jar to the Android application (right-click on Libraries under the project node and add the jar).
4) Add <uses-library> to the Android manifest. (erroneous and unnecessary)
Step 3 at least allows me to reference the library's classes in the application's source code, but the classes don't seem to actually be included at compile time. When I run the application, I get the following error in the log.
I/dalvikvm( 349): Could not find method mylibrarypackage.MyClass.myMethod, referenced from method myapplicationpackage.HomeActivity.onCreate
W/dalvikvm( 349): VFY: unable to resolve static method 985: Lmylibrarypackage/MyClass;.myMethod ()V
D/dalvikvm( 349): VFY: replacing opcode 0x71 at 0x000a
D/dalvikvm( 349): Making a copy of Lmyapplicationpackage/HomeActivity;.onCreate code (160 bytes)
D/AndroidRuntime( 349): Shutting down VM
W/dalvikvm( 349): threadid=3: thread exiting with uncaught exception (group=0x4001b188)
E/AndroidRuntime( 349): Uncaught handler: thread main exiting due to uncaught exception
E/AndroidRuntime( 349): java.lang.NoClassDefFoundError: mylibrarypackage.MyClass
E/AndroidRuntime( 349): at myapplicationpackage.HomeActivity.onCreate(HomeActivity.java:58)
E/AndroidRuntime( 349): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
E/AndroidRuntime( 349): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2417)
E/AndroidRuntime( 349): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2470)
E/AndroidRuntime( 349): at android.app.ActivityThread.access$2200(ActivityThread.java:119)
E/AndroidRuntime( 349): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1821)
E/AndroidRuntime( 349): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 349): at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime( 349): at android.app.ActivityThread.main(ActivityThread.java:4310)
E/AndroidRuntime( 349): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 349): at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime( 349): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
E/AndroidRuntime( 349): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
E/AndroidRuntime( 349): at dalvik.system.NativeStart.main(Native Method)
Do I have to add the library to the build path somewhere else? Am I missing something?
It appears I solved the problem.
I don't know if I missed a step when reading about how to use the nbandroid plugin, but the generated build-impl.xml doesn't seem to include any libraries I add with NetBeans when creating the APK.
This is the incriminating piece of ant script:
<target depends="init,compile,-pre-pre-jar,-pre-jar" name="-dex">
<exec executable="${dx}" failonerror="true">
<arg value="--dex"/>
<arg value="--output=${basedir}/${intermediate.dex}"/>
<arg value="--positions=lines"/>
<arg path="${build.classes.dir}"/>
</exec>
</target>
The library is included and the error mentioned in my question disappears if I add this last argument:
<arg path="${external.libs.dir}"/>
With external.libs.dir
pointing to the directory containing the library's jar.
Thanks to Christopher for making me look at the build.xml generated by the Android command line tools (the script generated when creating an Android project in NetBeans with the nbandroid plugin is quite different).
Addendum: Since I'm talking about NetBeans, another way of doing this is by overriding the -pre-jar
target in the project's build.xml, instead of the above change to build-impl.xml. This is done by adding the following to build.xml:
<target name="-pre-jar">
<copy todir="${build.classes.dir}">
<fileset dir="${external.libs.dir}" />
</copy>
</target>
This way, the library's jar is present along with the built classes, and automatically included.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With