From e5e43a2386fb4a4c2cb90d5a8d9bb5ca81a2675e Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 20 Jan 2014 14:02:24 +0100 Subject: Android: Don't crash on 100+ combo box items Local references are valid until the original native method returns (if it's a Java thread), or until the current thread is detached from the VM. This means that we have to manually manage local references and delete them when they are no longer in use, otherwise we will leak memory and flood JNI's local reference array. [ChangeLog][Android] Fixed crash on populating large combo boxes or menus. Task-number: QTBUG-36074 Change-Id: I7095bd1472f759be98183737a8d3912fa9763f30 Reviewed-by: Christian Stromme --- src/plugins/platforms/android/androidjnimenu.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src/plugins/platforms/android') diff --git a/src/plugins/platforms/android/androidjnimenu.cpp b/src/plugins/platforms/android/androidjnimenu.cpp index db9249e7fe..dc2afe2b03 100644 --- a/src/plugins/platforms/android/androidjnimenu.cpp +++ b/src/plugins/platforms/android/androidjnimenu.cpp @@ -198,9 +198,9 @@ namespace QtAndroidMenu static void fillMenuItem(JNIEnv *env, jobject menuItem, bool checkable, bool checked, bool enabled, bool visible, const QIcon &icon=QIcon()) { - env->CallObjectMethod(menuItem, setCheckableMenuItemMethodID, checkable); - env->CallObjectMethod(menuItem, setCheckedMenuItemMethodID, checked); - env->CallObjectMethod(menuItem, setEnabledMenuItemMethodID, enabled); + env->DeleteLocalRef(env->CallObjectMethod(menuItem, setCheckableMenuItemMethodID, checkable)); + env->DeleteLocalRef(env->CallObjectMethod(menuItem, setCheckedMenuItemMethodID, checked)); + env->DeleteLocalRef(env->CallObjectMethod(menuItem, setEnabledMenuItemMethodID, enabled)); if (!icon.isNull()) { // isNull() only checks the d pointer, not the actual image data. int sz = qMax(36, qgetenv("QT_ANDROID_APP_ICON_SIZE").toInt()); @@ -210,13 +210,13 @@ namespace QtAndroidMenu : QIcon::Disabled, QIcon::On).toImage(); if (!img.isNull()) { // Make sure we have a valid image. - env->CallObjectMethod(menuItem, - setIconMenuItemMethodID, - createBitmapDrawable(createBitmap(img, env), env)); + env->DeleteLocalRef(env->CallObjectMethod(menuItem, + setIconMenuItemMethodID, + createBitmapDrawable(createBitmap(img, env), env))); } } - env->CallObjectMethod(menuItem, setVisibleMenuItemMethodID, visible); + env->DeleteLocalRef(env->CallObjectMethod(menuItem, setVisibleMenuItemMethodID, visible)); } static int addAllMenuItemsToMenu(JNIEnv *env, jobject menu, QAndroidPlatformMenu *platformMenu) { @@ -242,6 +242,7 @@ namespace QtAndroidMenu item->isEnabled(), item->isVisible(), item->icon()); + env->DeleteLocalRef(menuItem); } return order; -- cgit v1.2.3