changeset 2483:9f7af6d8c6a4

Android: Fix signal handlers so they actually work. Create Weak Global References for the returned jobject handles. The jobject references passed from the event handler will be local references so we need to use IsSameObject() to compare the handles. Also create a more simple entrypoint to reduce calls.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Mon, 26 Apr 2021 21:08:02 +0000
parents 4888503c3e3e
children cb5b67154399
files android/DWindows.kt android/dw.cpp
diffstat 2 files changed, 28 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/android/DWindows.kt	Mon Apr 26 18:34:51 2021 +0000
+++ b/android/DWindows.kt	Mon Apr 26 21:08:02 2021 +0000
@@ -131,7 +131,7 @@
         val button = Button(this)
         button.text = text
         button.setOnClickListener {
-            eventHandler(button, null, 8, null, null, 0, 0, 0, 0)
+            eventHandlerSimple(button, 8)
         }
         return button
     }
@@ -151,7 +151,7 @@
         val radiobutton = RadioButton(this)
         radiobutton.text = text
         radiobutton.setOnClickListener {
-            eventHandler(radiobutton, null, 8, null, null, 0, 0, 0, 0)
+            eventHandlerSimple(radiobutton, 8)
         }
         return radiobutton
     }
@@ -161,7 +161,7 @@
         val checkbox = CheckBox(this)
         checkbox.text = text
         checkbox.setOnClickListener {
-            eventHandler(checkbox, null, 8, null, null, 0, 0, 0, 0)
+            eventHandlerSimple(checkbox, 8)
         }
         return checkbox
     }
@@ -184,6 +184,7 @@
      */
     external fun dwindowsInit(dataDir: String): String
     external fun eventHandler(obj1: View, obj2: View?, message: Int, str1: String?, str2: String?, int1: Int, int2: Int, int3: Int, int4: Int): Int
+    external fun eventHandlerSimple(obj1: View, message: Int)
 
     companion object
     {
--- a/android/dw.cpp	Mon Apr 26 18:34:51 2021 +0000
+++ b/android/dw.cpp	Mon Apr 26 21:08:02 2021 +0000
@@ -124,15 +124,16 @@
 SignalHandler *_dw_get_handler(HWND window, int messageid)
 {
     SignalHandler *tmp = DWRoot;
-
-    /* Find any callbacks for this function */
-    while(tmp)
-    {
-        if(tmp->message == messageid && window == tmp->window)
-        {
-            return tmp;
+    JNIEnv *env;
+
+    if((env = (JNIEnv *)pthread_getspecific(_dw_env_key))) {
+        /* Find any callbacks for this function */
+        while (tmp) {
+            if (tmp->message == messageid && env->IsSameObject(window, tmp->window)) {
+                return tmp;
+            }
+            tmp = tmp->next;
         }
-        tmp = tmp->next;
     }
     return NULL;
 }
@@ -352,6 +353,14 @@
     return _dw_event_handler(obj1, params, message);
 }
 
+/* A more simple method for quicker calls */
+JNIEXPORT void JNICALL
+Java_org_dbsoft_dwindows_dwtest_DWindows_eventHandlerSimple(JNIEnv* env, jobject obj, jobject obj1, jint message) {
+    void *params[8] = { NULL };
+
+    _dw_event_handler(obj1, params, message);
+}
+
 /* This function adds a signal handler callback into the linked list.
  */
 void _dw_new_signal(ULONG message, HWND window, int msgid, void *signalfunction, void *discfunc, void *data)
@@ -714,7 +723,7 @@
         // Get the method that you want to call
         jmethodID boxNew = env->GetMethodID(clazz, "boxNew", "(II)Landroid/widget/LinearLayout;");
         // Call the method on the object
-        jobject result = env->CallObjectMethod(_dw_obj, boxNew, type, pad);
+        jobject result = env->NewWeakGlobalRef(env->CallObjectMethod(_dw_obj, boxNew, type, pad));
         return result;
     }
     return 0;
@@ -900,7 +909,7 @@
         jmethodID buttonNew = env->GetMethodID(clazz, "buttonNew",
                                                "(Ljava/lang/String;I)Landroid/widget/Button;");
         // Call the method on the object
-        jobject result = env->CallObjectMethod(_dw_obj, buttonNew, jstr, (int)cid);
+        jobject result = env->NewWeakGlobalRef(env->CallObjectMethod(_dw_obj, buttonNew, jstr, (int)cid));
         return result;
     }
     return 0;
@@ -920,7 +929,7 @@
         jmethodID entryfieldNew = env->GetMethodID(clazz, "entryfieldNew",
                                                    "(Ljava/lang/String;II)Landroid/widget/EditText;");
         // Call the method on the object
-        jobject result = env->CallObjectMethod(_dw_obj, entryfieldNew, jstr, (int)cid, password);
+        jobject result = env->NewWeakGlobalRef(env->CallObjectMethod(_dw_obj, entryfieldNew, jstr, (int)cid, password));
         return result;
     }
     return 0;
@@ -1074,7 +1083,7 @@
         jmethodID radioButtonNew = env->GetMethodID(clazz, "radioButtonNew",
                                                     "(Ljava/lang/String;I)Landroid/widget/RadioButton;");
         // Call the method on the object
-        jobject result = env->CallObjectMethod(_dw_obj, radioButtonNew, jstr, (int)cid);
+        jobject result = env->NewWeakGlobalRef(env->CallObjectMethod(_dw_obj, radioButtonNew, jstr, (int)cid));
         return result;
     }
     return 0;
@@ -1206,7 +1215,7 @@
         jmethodID checkboxNew = env->GetMethodID(clazz, "checkboxNew",
                                                  "(Ljava/lang/String;I)Landroid/widget/CheckBox;");
         // Call the method on the object
-        jobject result = env->CallObjectMethod(_dw_obj, checkboxNew, jstr, (int)cid);
+        jobject result = env->NewWeakGlobalRef(env->CallObjectMethod(_dw_obj, checkboxNew, jstr, (int)cid));
         return result;
     }
     return 0;
@@ -1562,7 +1571,7 @@
         jmethodID textNew = env->GetMethodID(clazz, "textNew",
                                              "(Ljava/lang/String;II)Landroid/widget/TextView;");
         // Call the method on the object
-        jobject result = env->CallObjectMethod(_dw_obj, textNew, jstr, (int)cid, status);
+        jobject result = env->NewWeakGlobalRef(env->CallObjectMethod(_dw_obj, textNew, jstr, (int)cid, status));
         return result;
     }
     return 0;
@@ -2860,7 +2869,7 @@
         jmethodID windowNew = env->GetMethodID(clazz, "windowNew",
                                                "(Ljava/lang/String;I)Landroid/widget/LinearLayout;");
         // Call the method on the object
-        jobject result = env->CallObjectMethod(_dw_obj, windowNew, jstr, (int)flStyle);
+        jobject result = env->NewWeakGlobalRef(env->CallObjectMethod(_dw_obj, windowNew, jstr, (int)flStyle));
         return result;
     }
     return 0;