Utilizing JNIHelpers


#1

Hello!  I posted in response to an earlier related post but had no luck, so I'd like to present my issue more clearly in hopes of someone being able to help.. I am trying to use the JNIHelpers METHODS in order to be able to call Java functions from c++ (i.e. android.os.debug getNativeHeapSize()).  I'd like to do this to be able to programmatically probe how much RAM my app is using so that I can manage memory there.  I am trying this on a test app first to get all the steps down.  Which is seemingly impossible as of right now...

1. I created a new project with the Introjucer with XCode and Android Targets

2. I take the JUCE example, 'HelloWorld' and modify it to have 2 buttons and a display to allocate and free 20M and to someday display the memory available on the Android device.  This runs fine until I start trying to incorporate the JNI calls.

3. In my XCode Project, I modified the juceHeader.h and added this after all of the include statements

#if defined(JUCE_ANDROID)

namespace juce

{    

#include "modules/juce_core/native/juce_android_JNIHelpers.h"   

}

#endif

Both my main.cpp and MainComponent.h files include this file

4.  My 'call' to java...

in my mainComponent.cpp file, in my button clicked function, after I deal with what I want done natively, I call Java like so

#if JUCE_ANDROID   

        std::cout << "About to call to Java" << std::endl;

        const LocalRef<jstring> myText ((jstring) android.activity.callObjectMethod (JuceAppActivity.getMemInfo));        

        std::cout << "myMem from Java: " << myText << std::endl;        

#endif

5.  I added in my METHOD to the JNIHelpers.h file like so

...

 METHOD (scanFile,               "scanFile",             "(Ljava/lang/String;)V") \

 

//TESTCODE MINE

 METHOD (getMemInfo,             "getMemInfo",           "()Ljava/lang/String;")

 

DECLARE_JNI_CLASS (JuceAppActivity, JUCE_ANDROID_ACTIVITY_CLASSPATH);

...

So this function takes no arguments and will return a string to my C++ side of the world.

6.  In Eclipse, in my Java source file I have added in this function

    public final String getMemInfo ()

    {

        ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);

        int memoryClass = am.getMemoryClass();

        MemoryInfo memInfo = new MemoryInfo();

        long availableMegs = memInfo.availMem / 1048576L; 

        return Long.toString(availableMegs);

    }

I wanted to make sure first that I could go back and forth with a similar example I found on this forum posted by vipersnake, and was hoping to worry about the already implemented 'getNativeHeapSize' function later-- but I'll take that solution if anyone has got it!!

 

I know that the ACTIVITY CLASS NAME and PATH are set-- it says so in the Android.mk file.  I have double checked all of my file paths and it seems that it is all correct-- I have tried relative an absolute paths.  and I still continuously get this error whenever I try running ndk-build.  It compiles... but I am having an issue with the paths I think and I don't understand where I could be going wrong... 

 

ndk-build NDK_DEBUG=1 APP_OPTIM=debug

[armeabi] Gdbserver      : [arm-linux-androideabi-4.8] libs/armeabi/gdbserver

[armeabi] Gdbsetup       : libs/armeabi/gdb.setup

[armeabi-v7a] Gdbserver      : [arm-linux-androideabi-4.8] libs/armeabi-v7a/gdbserver

[armeabi-v7a] Gdbsetup       : libs/armeabi-v7a/gdb.setup

[armeabi] Compile++ thumb: juce_jni <= MainComponent.cpp

In file included from /Users/claudia/jniTestApp_MEM/JuceLibraryCode/JuceHeader.h:37:0,

                 from jni/../../../Source/MainComponent.h:24,

                 from jni/../../../Source/MainComponent.cpp:23:

/Users/claudia/jniTestApp_MEM/JuceLibraryCode/modules/juce_core/native/juce_android_JNIHelpers.h:37:8: error: 'JNIEnv' does not name a type

 extern JNIEnv* getEnv() noexcept;

        ^

/Users/claudia/jniTestApp_MEM/JuceLibraryCode/modules/juce_core/native/juce_android_JNIHelpers.h:44:40: error: expected ')' before 'o'

     inline explicit GlobalRef (jobject o)       : obj (retain (o)) {}

 And the errors just keep going.  Does anyone happen to see a step that I may have missed?? 

 

Thank you!!!!


#2

You have a namespace issue somewhere. Overall the code looks correct. You are into your C++ code so that is a good thing. 

 

I would not recommend (and can't see how that would work) changing the JuceHeader.h especially considering it will be re-generated and your changes lost.

 

Put:

 

#if defined(JUCE_ANDROID)

namespace juce

{    

#include "modules/juce_core/native/juce_android_JNIHelpers.h"   

}

#endif

 

at the top of your MainComponent.cpp after you include JuceHeaders.

 

You can always PM me a link to the project and I will take a look.

 

 

Michael

 


#3

In the past, I have also updated juce_android_JNIHelpers code to include some functions I needed to call on the Java side. Now that I update my app, I need to include those functions again since I have a new version of the JUCE lib.

I was wondering if there’s any way to handle this without modifying the original JUCE code, which I obviously try to avoid.