android: Fix crash when setting window title on wrong thread

This commit is contained in:
rdb 2025-12-06 21:08:23 +01:00
parent 8fb23c5599
commit ba6b66fbb6
4 changed files with 21 additions and 14 deletions

View File

@ -4946,12 +4946,14 @@ if GetTarget() == 'android':
TargetAdd('org/panda3d/android/NativeOStream.class', opts=OPTS, input='NativeOStream.java')
TargetAdd('org/panda3d/android/PandaActivity.class', opts=OPTS, input='PandaActivity.java')
TargetAdd('org/panda3d/android/PandaActivity$1.class', opts=OPTS+['DEPENDENCYONLY'], input='PandaActivity.java')
TargetAdd('org/panda3d/android/PandaActivity$2.class', opts=OPTS+['DEPENDENCYONLY'], input='PandaActivity.java')
TargetAdd('org/panda3d/android/PythonActivity.class', opts=OPTS, input='PythonActivity.java')
TargetAdd('classes.dex', input='org/panda3d/android/NativeIStream.class')
TargetAdd('classes.dex', input='org/panda3d/android/NativeOStream.class')
TargetAdd('classes.dex', input='org/panda3d/android/PandaActivity.class')
TargetAdd('classes.dex', input='org/panda3d/android/PandaActivity$1.class')
TargetAdd('classes.dex', input='org/panda3d/android/PandaActivity$2.class')
TargetAdd('classes.dex', input='org/panda3d/android/PythonActivity.class')
TargetAdd('p3android_composite1.obj', opts=OPTS, input='p3android_composite1.cxx')

View File

@ -159,6 +159,18 @@ public class PandaActivity extends NativeActivity {
return getCacheDir().toString();
}
/**
* Sets the window title.
*/
public void setWindowTitle(final CharSequence title) {
final PandaActivity activity = this;
runOnUiThread(new Runnable() {
public void run() {
activity.setTitle(title);
}
});
}
/**
* Shows a pop-up notification.
*/

View File

@ -27,11 +27,9 @@ jmethodID jni_PandaActivity_readBitmap;
jmethodID jni_PandaActivity_createBitmap;
jmethodID jni_PandaActivity_compressBitmap;
jmethodID jni_PandaActivity_showToast;
jmethodID jni_PandaActivity_setWindowTitle;
jmethodID jni_PandaActivity_findLibrary;
jclass jni_Activity;
jmethodID jni_Activity_setTitle;
jclass jni_BitmapFactory_Options;
jfieldID jni_BitmapFactory_Options_outWidth;
jfieldID jni_BitmapFactory_Options_outHeight;
@ -81,17 +79,15 @@ jint JNI_OnLoad(JavaVM *jvm, void *reserved) {
jni_PandaActivity_compressBitmap = env->GetStaticMethodID(jni_PandaActivity,
"compressBitmap", "(Landroid/graphics/Bitmap;IIJ)Z");
jni_PandaActivity_setWindowTitle = env->GetMethodID(jni_PandaActivity,
"setWindowTitle", "(Ljava/lang/CharSequence;)V");
jni_PandaActivity_showToast = env->GetMethodID(jni_PandaActivity,
"showToast", "(Ljava/lang/String;I)V");
jni_PandaActivity_findLibrary = env->GetMethodID(jni_PandaActivity,
"findLibrary", "(Ljava/lang/String;)Ljava/lang/String;");
jni_Activity = env->FindClass("android/app/Activity");
jni_Activity = (jclass) env->NewGlobalRef(jni_Activity);
jni_Activity_setTitle = env->GetMethodID(jni_Activity,
"setTitle", "(Ljava/lang/CharSequence;)V");
jni_BitmapFactory_Options = env->FindClass("android/graphics/BitmapFactory$Options");
jni_BitmapFactory_Options = (jclass) env->NewGlobalRef(jni_BitmapFactory_Options);
@ -130,7 +126,6 @@ void JNI_OnUnload(JavaVM *jvm, void *reserved) {
nassertv(env != nullptr);
env->DeleteGlobalRef(jni_PandaActivity);
env->DeleteGlobalRef(jni_Activity);
env->DeleteGlobalRef(jni_BitmapFactory_Options);
// These will no longer work without JNI, so unregister them.
@ -174,14 +169,14 @@ Filename android_find_library(ANativeActivity *activity, const std::string &lib)
* Sets the window title of the activity.
*/
void android_set_title(ANativeActivity *activity, const std::string &title) {
nassertv(jni_Activity_setTitle);
nassertv(jni_PandaActivity_setWindowTitle);
Thread *thread = Thread::get_current_thread();
JNIEnv *env = thread->get_jni_env();
nassertv(env != nullptr);
jstring jmsg = env->NewStringUTF(title.c_str());
env->CallVoidMethod(activity->clazz, jni_Activity_setTitle, jmsg);
env->CallVoidMethod(activity->clazz, jni_PandaActivity_setWindowTitle, jmsg);
env->DeleteLocalRef(jmsg);
}

View File

@ -33,11 +33,9 @@ extern jmethodID jni_PandaActivity_readBitmapHeader;
extern jmethodID jni_PandaActivity_readBitmap;
extern jmethodID jni_PandaActivity_createBitmap;
extern jmethodID jni_PandaActivity_compressBitmap;
extern jmethodID jni_PandaActivity_setWindowTitle;
extern jmethodID jni_PandaActivity_showToast;
extern jclass jni_Activity;
extern jmethodID jni_Activity_setTitle;
extern jclass jni_BitmapFactory_Options;
extern jfieldID jni_BitmapFactory_Options_outWidth;
extern jfieldID jni_BitmapFactory_Options_outHeight;