2

As the title suggested, How can I call Java function from C++ if the function is from a different java activity class?

All of the sample and tutorials calls C++ function and java back and forth but the caller is the class and the JNIEnv and jobject are passed from java thru JNI. But what if the function that needed to be called is from a different java activity class? How to do this? passing the "this" of the activity did not work

Here is sample layout of classes

Activity class

public class MainActivity extends Activity {
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);

          JNIAdapter.launch(); 
      }

      private void DisplayLoginDialog() 
      {
          //...
      }
}

JNIAdapter.class

public class JNIAdapter {
    static {
       System.loadLibrary("jnisample-lib");
    }

     public static native void launch();
}

jnisample.cpp

extern "C"
JNIEXPORT void JNICALL
Java_com_JNIAdapter_launch(JNIEnv *env,jobject object)
{
       jclass dataClass = env->FindClass("com/game/ramo/MainActivity");
       jmethodID javaMethodRef = env->GetMethodID(dataClass, "DisplayLoginDialog", "()V");
       env->CallVoidMethod(object, javaMethodRef);
}

In the above code, using the jobject, refers to the JNIAdapter class and not the Activity hence the DisplayLoginDialog() is not called. How to do this?

5
  • you need to pass another jobject parameter pointing to your com.game.ramo.GLRenderer object Commented Sep 18, 2018 at 5:23
  • sorry @pskink the line where the "GLRenderer" should be is "MainActivity" I edited my original post, anyway, if I pass another jobject from java, how do i specify it? do i just pass the "this" context of mainactivity? Commented Sep 18, 2018 at 5:42
  • yes, pass this Commented Sep 18, 2018 at 5:59
  • tried it with no luck, so i changed Java_com_JNIAdapter_launch() and added 3rd parameter with jobject and passed android.app.Activity with "this" but im getting SIGABRT when calling the line env->CallVoidMethod(activity, javaMethodRef) Commented Sep 18, 2018 at 7:05
  • 1
    Where is your error handling? You should always check the result of JNI calls like FindClass and GetMethodID. Commented Sep 18, 2018 at 9:00

1 Answer 1

1

Your small example (I understand that you reduced all details not relevant to the specific problem, that's very nice!) could run without native method. JNIAdaptor.launch() could be pure Java. So, to begin with, rewrite it in Java and make sure it works.

The issues could be that MainActivity.DisplayLoginDialog() may expect its parent activity to be in the foreground, or in some specific state. This is easier to fix in pure Java.

After that, the JNI code you wrote should run without problems.

Sign up to request clarification or add additional context in comments.

2 Comments

thanks for the reply, but youre right, the code i posted above is just for demonstration of the problem and not what exactly what is happening, in reality there is more happening in the call to launch in the JNI-C++ side like initialization and other C++ related code hence there is a JNI call, then after the C++ logic code the java login function is called to display the pop-up login window (in java) hence the code structure, so NO, the JNIAdapter.launch cannot be a pure java sorry. but if you meant for testing to see the dialog was launch without the JNI, then yes it was correctly.
Exactly, I only meant foregoing JNI for testing, because if you can fulfill the call in pure Java, there is no reason why via JNI you could not do the same

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.