JuceDemo for Android

Hello,

Could someone guide me explaining how to open the JuceDemo under Eclipse making it works for Android starting with the NDK installation? That would be really helpful. Thank you for your work

If you are working in Windows, you’re on your own. NDK development is pretty quirky there (well, quirkier).

  1. Install the latest SDK
  2. Install the latest NDK

It makes things smoother if they are both installed at ~/SDKs. This isn’t essential, but it is what Introjucer, etc. defaults to.

  1. Build the NDK samples

You may find that you have to modify your search paths to get everything to work from the command line (launching emulators, etc.)

  1. Get the latest Juce tip
  2. Build the Introjucer for your platform
  3. Run the Intorjucer, open the Introjucer project file for the Juce Demo
  4. Save the project

This rebuilds the ‘Builds’ folder to match the latest code/bindings.

  1. From a terminal prompt, go to the Builds/Android folder under the JuceDemo project.
  2. Run “ant debug” or “ant release”

This should compile the library for legacy arm and arm 7 and create an apk file. At this point, you could even use the command line Anrdoid tools to run it, but…

  1. Open Eclipse
  2. New Project
  3. Project from Existing Source
  4. Browse to the same Builds/Android folder
  5. Be sure to ‘next’ through all the options
  6. Create a suitable “AVD” (emulator)
  7. Select the project and hit “run”

Note, this will not generally recompile your NDK code. It just does Java and packaging. There are a couple of plug-ins, as well as a slew of contradictory instructions floating around on how to manually configure Eclipse for NDK compilation. I can attest that you can get it to work. Source level debugging with gdb-ndk, no. I can get it to work with simple C, but it is hopelessly confused with Juce.

What threw me when I started was that juce was not working correctly with “ICS” (4.0x). So even when I got building all working, it wasn’t working. But I have tried the tip from a week or so ago (pre flu) with 2.1 and it works fine.

Thank you very much for the answer. However, I still have a problem. Here is what I get for the ninth task (running ant):

"iMac-de-emmanuel:Android Stagiaire$ ant
Buildfile: /Users/Stagiaire/Desktop/Olivier/JUCE/juce/extras/JuceDemo/Builds/Android/build.xml

BUILD FAILED
/Users/Stagiaire/Desktop/Olivier/JUCE/juce/extras/JuceDemo/Builds/Android/build.xml:12: taskdef class com.android.ant.SetupTask cannot be found
using the classloader AntClassLoader[]

Total time: 0 seconds
iMac-de-emmanuel:Android Stagiaire$ "

I don’t understand why I get this. Some say that it means that my SDK have issues, but it appears it doesn’t. I already tried a quick calculator app under eclipse and was able to compile and use it on the avm so things should be ok (sdk+adt plugin).
Do you have an idea?

Thank you again

It does sound like SDK installation is incorrect or incomplete. Are you sure that sdk.dir is set correctly?

You can also follow the path out and see if “com.android.ant.SetupTask” is where the build.xml file expects it. Something like:

grep -ri “com.android.ant.SetupTask” *

Inside your SDK folder should give you the actual location. This is, BTW, a very common google search. Generally it is missing paths or SDK setup.

Also, Eclipse doesn’t really use the ANT system (which is part of the Java JDK, not the Android SDK), but it’s own SDK paths, so your test doesn’t really tell us much.

Alright, so it definitely was a path problem. I had to add the tools and platform-tools to the System path in order to launch the android project update command that changed the build.xml file. I’ve been able to run ant and have a succesful build. Everything was ok so far until I hit the “run” button under eclipse where the avd shows a message saying “Unfortunatly, Juce Demo has stopped”, with no particular messages in the console, but this written in the logcat:

03-09 15:06:45.617: E/AndroidRuntime(539): FATAL EXCEPTION: main
03-09 15:06:45.617: E/AndroidRuntime(539): java.lang.ExceptionInInitializerError
03-09 15:06:45.617: E/AndroidRuntime(539): at java.lang.Class.newInstanceImpl(Native Method)
03-09 15:06:45.617: E/AndroidRuntime(539): at java.lang.Class.newInstance(Class.java:1319)
03-09 15:06:45.617: E/AndroidRuntime(539): at android.app.Instrumentation.newActivity(Instrumentation.java:1023)
03-09 15:06:45.617: E/AndroidRuntime(539): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1871)
03-09 15:06:45.617: E/AndroidRuntime(539): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
03-09 15:06:45.617: E/AndroidRuntime(539): at android.app.ActivityThread.access$600(ActivityThread.java:123)
03-09 15:06:45.617: E/AndroidRuntime(539): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
03-09 15:06:45.617: E/AndroidRuntime(539): at android.os.Handler.dispatchMessage(Handler.java:99)
03-09 15:06:45.617: E/AndroidRuntime(539): at android.os.Looper.loop(Looper.java:137)
03-09 15:06:45.617: E/AndroidRuntime(539): at android.app.ActivityThread.main(ActivityThread.java:4424)
03-09 15:06:45.617: E/AndroidRuntime(539): at java.lang.reflect.Method.invokeNative(Native Method)
03-09 15:06:45.617: E/AndroidRuntime(539): at java.lang.reflect.Method.invoke(Method.java:511)
03-09 15:06:45.617: E/AndroidRuntime(539): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
03-09 15:06:45.617: E/AndroidRuntime(539): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
03-09 15:06:45.617: E/AndroidRuntime(539): at dalvik.system.NativeStart.main(Native Method)
03-09 15:06:45.617: E/AndroidRuntime(539): Caused by: java.lang.UnsatisfiedLinkError: Couldn’t load juce_jni: findLibrary returned null
03-09 15:06:45.617: E/AndroidRuntime(539): at java.lang.Runtime.loadLibrary(Runtime.java:365)
03-09 15:06:45.617: E/AndroidRuntime(539): at java.lang.System.loadLibrary(System.java:535)
03-09 15:06:45.617: E/AndroidRuntime(539): at com.juce.JuceAppActivity.(JuceAppActivity.java:56)
03-09 15:06:45.617: E/AndroidRuntime(539): … 15 more

Looks like your app file doesn’t contain the native code for some reason.

I agree, it looks like there is no .so file in your .apk package.

There are a bunch of threads on this in the Android developer forums. You might consider this Eclipse plug in:

If you add the native code support, you can right click on a project, and add android native support. This does all the voodoo to compile the c++ and link in the libraries for you.

I also have trouble getting the demo to run on a virtual machine. Logcat tells me this:

05-13 18:59:55.186: D/AndroidRuntime(528): Shutting down VM 05-13 18:59:55.186: W/dalvikvm(528): threadid=1: thread exiting with uncaught exception (group=0x409c01f8) 05-13 18:59:55.206: E/AndroidRuntime(528): FATAL EXCEPTION: main 05-13 18:59:55.206: E/AndroidRuntime(528): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.juce/com.juce.JuceAppActivity}: java.lang.ClassNotFoundException: com.juce.JuceAppActivity 05-13 18:59:55.206: E/AndroidRuntime(528): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1880) 05-13 18:59:55.206: E/AndroidRuntime(528): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981) 05-13 18:59:55.206: E/AndroidRuntime(528): at android.app.ActivityThread.access$600(ActivityThread.java:123) 05-13 18:59:55.206: E/AndroidRuntime(528): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147) 05-13 18:59:55.206: E/AndroidRuntime(528): at android.os.Handler.dispatchMessage(Handler.java:99) 05-13 18:59:55.206: E/AndroidRuntime(528): at android.os.Looper.loop(Looper.java:137) 05-13 18:59:55.206: E/AndroidRuntime(528): at android.app.ActivityThread.main(ActivityThread.java:4424) 05-13 18:59:55.206: E/AndroidRuntime(528): at java.lang.reflect.Method.invokeNative(Native Method) 05-13 18:59:55.206: E/AndroidRuntime(528): at java.lang.reflect.Method.invoke(Method.java:511) 05-13 18:59:55.206: E/AndroidRuntime(528): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 05-13 18:59:55.206: E/AndroidRuntime(528): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 05-13 18:59:55.206: E/AndroidRuntime(528): at dalvik.system.NativeStart.main(Native Method) 05-13 18:59:55.206: E/AndroidRuntime(528): Caused by: java.lang.ClassNotFoundException: com.juce.JuceAppActivity 05-13 18:59:55.206: E/AndroidRuntime(528): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61) 05-13 18:59:55.206: E/AndroidRuntime(528): at java.lang.ClassLoader.loadClass(ClassLoader.java:501) 05-13 18:59:55.206: E/AndroidRuntime(528): at java.lang.ClassLoader.loadClass(ClassLoader.java:461) 05-13 18:59:55.206: E/AndroidRuntime(528): at android.app.Instrumentation.newActivity(Instrumentation.java:1023) 05-13 18:59:55.206: E/AndroidRuntime(528): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1871) 05-13 18:59:55.206: E/AndroidRuntime(528): ... 11 more

Knowing not much about Android at this point, does anybody know what is going wrong here? I’ve installed Sequoyah and added native support already.

You seem to have a miss-match between your native code and java helper. Are you building with the latest Juce and did you use Introjucer to create the project?

Also, have you tried just compiling from the command line?

I did use the Introjucer… checked out the latest JUCE version yesterday and tried again. First I had to disable OpenGL in the Introjucer, then, in line 114 of MainDemoWindow.cpp, I edited a non-if-ed OpenGL call to

#if JUCE_OPENGL const int currentEngine = openGLWrapperComp != nullptr ? engines.size() - 1 : getPeer()->getCurrentRenderingEngine(); #else const int currentEngine = getPeer()->getCurrentRenderingEngine(); #endif

and in ThreadingDemo.cpp in line 279,

pool.addJob (newBall) has to be replaced with

pool.addJob (newBall,true) (or “false”, I’m not sure here). Now I’m stuck with #error "The JUCE_ANDROID_ACTIVITY_CLASSNAME and JUCE_ANDROID_ACTIVITY_CLASSPATH macros must be set!" … where do these come into play?

The macros are set based on the bundle identifier you give in the Introjucer. Every class has to have a unique identifier on the Android device, so you have to provide the unique name for the java helper classes that Juce uses to integrate with the system.

However, I’m puzzled that you had to disable OpenGL. I did an Android built weeks ago when Jules first released the new OpenGL renderer. The default manifest created by the Introjucer selects an target SDK high enough to support OpenGL.

Likewise, I’m puzzled that your JuceDemo code is out of sync on thread pools. This might be related to your OpenGL problem. Up until the new OpenGL renderer, the Android build had some quasi OpenGL support code that didn’t really function correctly yet. Later today I’ll pull the latest tip and do an Android build myself.

Ok, I was on JUCE 2.0.17 and used the Introjucer to update the modules to 2.0.21 (leaving the Introjucer still in 2.0.17 state, as far as I can see, which probably explains the issues). After a complete, fresh JUCE update Eclipse still doesn’t want to build, but ant does, and Eclipse runs the demo on the simulator afterwards. So far, so good…

I just did a build, both from ANT, and from Eclipse. Setting up the native build stuff manually is tricky, the easiest way to build in Eclipse is Sequoa (sp?) plug-in. Basically:

New Project
From Existing Source
Browse to Builds/Android folder
Next through remainder of wizard
Right click on project in Workspace
Select Android Tools / Add Native Support
Switch to “Native” view
Build

Though I generally build using ANT and invoke the emulator from the command line as well (I despise Eclipse).

Hi All,
A couple of days ago I decided to get a test project into Android, and haven’t succeeded.
I downloaded and setup the SDK, platform and NDK. Also created a simple Android “hello world” app in Eclipse just to check that things work.
Then I proceeded to compile and run Juce Demo on Android. First I ran into some issues with Introjucer when trying to update sdk and ndk paths, where it wouldn’t want to save anything, claiming that “juice_core” had to be selected (and it was), so I updated to the latest tip of JUCE and still got that, so I decided to begin a new empty JUCE project. That saved Ok, but when running ant, I got the “tasked class com.android.ant.SetupTask cannot be found” issue. Since then, I’ve been trying things, changing paths, google-ing things and all of the responses point to a path issue, but I’ve checked them many times, so I ran the grep command mentioned above, and the fact is, the class is nowhere to be found in the SDK folder :-(. Haven’t found any pointers as to what to do in this case, but I tried “updating the project” using the android tool (first I backuped the build.xml created by introjucer) and noticed that the one auto created didn’t have anything about setup task, but it looked drastically different than the juce generated on, so I re copied the one generated by juce, but commented out the line with the “SetupTask” stuff.
It built. Then I opened up eclipse, imported the project, and it ran.
I tried the same with the demo app, but it failed to compile. Anyone knows what is that SetupTask supposed to do? Why is it not in the most recent SDK? I IntroJucer outdated and generates a build.xml that doesn’t work with the latest sdk? Other than that “empty” project I was able to compile, I haven’t been able to solve the Demo build for android, nor my other test project. Any ideas? (btw, I’m using OS X Lion, if it matters).

Thanks in advance.

Google might have released a new API since I last built it… They seem to do that regularly, and it usually breaks everything. I’ll check it when I get chance.

FWIW, the NDK rev’ed to 8 in May, and there is an update to the SDK Tools and SDK Platform-Tools since I last built. I was at 16/10, they are now at 20/12. I’ve been meaning to check them out, but the stupid Android SDK Manager has failed every time I’ve tried to update.

Thanks both for the responses, and just to clarify, yes, I am using ndk-r8 and the SDK and Plat Tools 20 and 12.

Well, I updated platform tools to 20/12 and everything built just fine for Android 4.0.3 (API 15) with NDK rev7.

As soon as I have a few minutes, I’ll try the Android 4.1 (API 16) SDK and the NDK rev8 (I’ll upgrade them one at a time).

Interesting. I’m actually trying with API 15 (4.03). NDK r8, but I think that should be unrelated to where the “missing” class is supposed to be. :-(.

FWIW, i just updated to 20/12 and i have the same problem. everything was ok on 19. I also updated to the latest JUCE and re-generated my project files.

removing the line

<taskdef name="setup" classname="com.android.ant.SetupTask" classpathref="android.antlibs"/>

seems to make it build. im not sure what this line does. perhaps it isn’t needed anymore. more likely, something will break later? debugging?

FYI, im using ndk-r8 and building against api 10 (for my phone). I think the API level doesnt affect it though.

– hugh.