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 <christian.stromme@digia.com>
This commit is contained in:
Eskil Abrahamsen Blomfeldt 2014-01-20 14:02:24 +01:00 committed by The Qt Project
parent 1e20115cf0
commit e5e43a2386

View File

@ -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;