# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1619471282 0 # Node ID 9f7af6d8c6a46a916330fdcbc4b6ab8a4b4005f4 # Parent 4888503c3e3e56d4160c4a114b4cc4d7b4eda287 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. diff -r 4888503c3e3e -r 9f7af6d8c6a4 android/DWindows.kt --- 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 { diff -r 4888503c3e3e -r 9f7af6d8c6a4 android/dw.cpp --- 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;