Android: use 'RegisterNatives' to export the native methods
authorSylvain Becker <sylvain.becker@gmail.com>
Thu, 12 Dec 2019 18:38:36 +0100
changeset 13335386769477625
parent 13334 82b3162e2724
child 13336 e15228a0c1b0
Android: use 'RegisterNatives' to export the native methods

"The advantages of RegisterNatives are that you get up-front checking
that the symbols exist, plus you can have smaller and faster shared
libraries by not exporting anything but JNI_OnLoad"

https://developer.android.com/training/articles/perf-jni#native-libraries
src/core/android/SDL_android.c
     1.1 --- a/src/core/android/SDL_android.c	Wed Dec 11 19:24:40 2019 -0800
     1.2 +++ b/src/core/android/SDL_android.c	Thu Dec 12 18:38:36 2019 +0100
     1.3 @@ -147,9 +147,6 @@
     1.4          JNIEnv *env, jclass cls,
     1.5          jstring name, jstring value);
     1.6  
     1.7 -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeEnvironmentVariablesSet)(
     1.8 -        JNIEnv *env, jclass cls);
     1.9 -
    1.10  JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeOrientationChanged)(
    1.11          JNIEnv *env, jclass cls,
    1.12          jint orientation);
    1.13 @@ -158,6 +155,35 @@
    1.14          JNIEnv* env, jclass cls,
    1.15          jint touchId, jstring name);
    1.16  
    1.17 +static JNINativeMethod SDLActivity_tab[] = {
    1.18 +    { "nativeSetupJNI",             "()I", SDL_JAVA_INTERFACE(nativeSetupJNI) },
    1.19 +    { "nativeRunMain",              "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)I", SDL_JAVA_INTERFACE(nativeRunMain) },
    1.20 +    { "onNativeDropFile",           "(Ljava/lang/String;)V", SDL_JAVA_INTERFACE(onNativeDropFile) },
    1.21 +    { "nativeSetScreenResolution",  "(IIIIIF)V", SDL_JAVA_INTERFACE(nativeSetScreenResolution) },
    1.22 +    { "onNativeResize",             "()V", SDL_JAVA_INTERFACE(onNativeResize) },
    1.23 +    { "onNativeSurfaceCreated",     "()V", SDL_JAVA_INTERFACE(onNativeSurfaceCreated) },
    1.24 +    { "onNativeSurfaceChanged",     "()V", SDL_JAVA_INTERFACE(onNativeSurfaceChanged) },
    1.25 +    { "onNativeSurfaceDestroyed",   "()V", SDL_JAVA_INTERFACE(onNativeSurfaceDestroyed) },
    1.26 +    { "onNativeKeyDown",            "(I)V", SDL_JAVA_INTERFACE(onNativeKeyDown) },
    1.27 +    { "onNativeKeyUp",              "(I)V", SDL_JAVA_INTERFACE(onNativeKeyUp) },
    1.28 +    { "onNativeSoftReturnKey",      "()Z", SDL_JAVA_INTERFACE(onNativeSoftReturnKey) },
    1.29 +    { "onNativeKeyboardFocusLost",  "()V", SDL_JAVA_INTERFACE(onNativeKeyboardFocusLost) },
    1.30 +    { "onNativeTouch",              "(IIIFFF)V", SDL_JAVA_INTERFACE(onNativeTouch) },
    1.31 +    { "onNativeMouse",              "(IIFFZ)V", SDL_JAVA_INTERFACE(onNativeMouse) },
    1.32 +    { "onNativeAccel",              "(FFF)V", SDL_JAVA_INTERFACE(onNativeAccel) },
    1.33 +    { "onNativeClipboardChanged",   "()V", SDL_JAVA_INTERFACE(onNativeClipboardChanged) },
    1.34 +    { "nativeLowMemory",            "()V", SDL_JAVA_INTERFACE(nativeLowMemory) },
    1.35 +    { "nativeSendQuit",             "()V", SDL_JAVA_INTERFACE(nativeSendQuit) },
    1.36 +    { "nativeQuit",                 "()V", SDL_JAVA_INTERFACE(nativeQuit) },
    1.37 +    { "nativePause",                "()V", SDL_JAVA_INTERFACE(nativePause) },
    1.38 +    { "nativeResume",               "()V", SDL_JAVA_INTERFACE(nativeResume) },
    1.39 +    { "nativeFocusChanged",         "(Z)V", SDL_JAVA_INTERFACE(nativeFocusChanged) },
    1.40 +    { "nativeGetHint",              "(Ljava/lang/String;)Ljava/lang/String;", SDL_JAVA_INTERFACE(nativeGetHint) },
    1.41 +    { "nativeSetenv",               "(Ljava/lang/String;Ljava/lang/String;)V", SDL_JAVA_INTERFACE(nativeSetenv) },
    1.42 +    { "onNativeOrientationChanged", "(I)V", SDL_JAVA_INTERFACE(onNativeOrientationChanged) },
    1.43 +    { "nativeAddTouch",             "(ILjava/lang/String;)V", SDL_JAVA_INTERFACE(nativeAddTouch) }
    1.44 +};
    1.45 +
    1.46  /* Java class SDLInputConnection */
    1.47  JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)(
    1.48          JNIEnv *env, jclass cls,
    1.49 @@ -171,10 +197,20 @@
    1.50          JNIEnv *env, jclass cls,
    1.51          jstring text, jint newCursorPosition);
    1.52  
    1.53 +static JNINativeMethod SDLInputConnection_tab[] = {
    1.54 +    { "nativeCommitText",                   "(Ljava/lang/String;I)V", SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText) },
    1.55 +    { "nativeGenerateScancodeForUnichar",   "(C)V", SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancodeForUnichar) },
    1.56 +    { "nativeSetComposingText",             "(Ljava/lang/String;I)V", SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingText) }
    1.57 +};
    1.58 +
    1.59  /* Java class SDLAudioManager */
    1.60  JNIEXPORT void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)(
    1.61          JNIEnv *env, jclass jcls);
    1.62  
    1.63 +static JNINativeMethod SDLAudioManager_tab[] = {
    1.64 +    { "nativeSetupJNI", "()I", SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI) }
    1.65 +};
    1.66 +
    1.67  /* Java class SDLControllerManager */
    1.68  JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)(
    1.69          JNIEnv *env, jclass jcls);
    1.70 @@ -212,6 +248,17 @@
    1.71          JNIEnv *env, jclass jcls,
    1.72          jint device_id);
    1.73  
    1.74 +static JNINativeMethod SDLControllerManager_tab[] = {
    1.75 +    { "nativeSetupJNI",         "()I", SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI) },
    1.76 +    { "onNativePadDown",        "(II)I", SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown) },
    1.77 +    { "onNativePadUp",          "(II)I", SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp) },
    1.78 +    { "onNativeJoy",            "(IIF)V", SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoy) },
    1.79 +    { "onNativeHat",            "(IIII)V", SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat) },
    1.80 +    { "nativeAddJoystick",      "(ILjava/lang/String;Ljava/lang/String;IIZIIII)I", SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick) },
    1.81 +    { "nativeRemoveJoystick",   "(I)I", SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick) },
    1.82 +    { "nativeAddHaptic",        "(ILjava/lang/String;)I", SDL_JAVA_CONTROLLER_INTERFACE(nativeAddHaptic) },
    1.83 +    { "nativeRemoveHaptic",     "(I)I", SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic) }
    1.84 +};
    1.85  
    1.86  
    1.87  /* Uncomment this to log messages entering and exiting methods in this file */
    1.88 @@ -424,10 +471,32 @@
    1.89      }
    1.90  }
    1.91  
    1.92 +static void
    1.93 +register_methods(JNIEnv *env, const char *classname, JNINativeMethod *methods, int nb) 
    1.94 +{
    1.95 +    jclass clazz = (*env)->FindClass(env, classname);
    1.96 +    if (clazz == NULL || (*env)->RegisterNatives(env, clazz, methods, nb) < 0) {
    1.97 +        __android_log_print(ANDROID_LOG_ERROR, "SDL", "Failed to register methods of %s", classname);
    1.98 +        return;
    1.99 +    }
   1.100 +}
   1.101 +
   1.102  /* Library init */
   1.103  JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
   1.104  {
   1.105      mJavaVM = vm;
   1.106 +    JNIEnv *env = NULL;
   1.107 +
   1.108 +    if ((*mJavaVM)->GetEnv(mJavaVM, (void **)&env, JNI_VERSION_1_4) != JNI_OK) {
   1.109 +        __android_log_print(ANDROID_LOG_ERROR, "SDL", "Failed to get JNI Env");
   1.110 +        return JNI_VERSION_1_4;
   1.111 +    }
   1.112 +
   1.113 +    register_methods(env, "org/libsdl/app/SDLActivity", SDLActivity_tab, sizeof (SDLActivity_tab) / sizeof (SDLActivity_tab[0]));
   1.114 +    register_methods(env, "org/libsdl/app/SDLInputConnection", SDLInputConnection_tab, sizeof (SDLInputConnection_tab) / sizeof (SDLInputConnection_tab[0]));
   1.115 +    register_methods(env, "org/libsdl/app/SDLAudioManager", SDLAudioManager_tab, sizeof (SDLAudioManager_tab) / sizeof (SDLAudioManager_tab[0]));
   1.116 +    register_methods(env, "org/libsdl/app/SDLControllerManager", SDLControllerManager_tab, sizeof (SDLControllerManager_tab) / sizeof (SDLControllerManager_tab[0]));
   1.117 +
   1.118      return JNI_VERSION_1_4;
   1.119  }
   1.120