Android: don't crash on exit
We have to call DetachCurrentThread() for each time we call AttachCurrentThread(). Fortunately we have this convenience class that we prepared earlier. Task-number: QTBUG-30847 Change-Id: I5ffb94b336d3787a3bae197bab22b91770d58848 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
This commit is contained in:
parent
8d1b8b97ac
commit
6c719079ec
@ -237,13 +237,11 @@ static JNINativeMethod methods[] = {
|
||||
|
||||
QAndroidInputContext::QAndroidInputContext():QPlatformInputContext()
|
||||
{
|
||||
JNIEnv *env = 0;
|
||||
if (QtAndroid::javaVM()->AttachCurrentThread(&env, NULL) < 0) {
|
||||
qCritical() << "AttachCurrentThread failed";
|
||||
QtAndroid::AttachedJNIEnv env;
|
||||
if (!env.jniEnv)
|
||||
return;
|
||||
}
|
||||
|
||||
jclass clazz = QtAndroid::findClass(QtNativeInputConnectionClassName, env);
|
||||
jclass clazz = QtAndroid::findClass(QtNativeInputConnectionClassName, env.jniEnv);
|
||||
if (clazz == NULL) {
|
||||
qCritical() << "Native registration unable to find class '"
|
||||
<< QtNativeInputConnectionClassName
|
||||
@ -251,14 +249,14 @@ QAndroidInputContext::QAndroidInputContext():QPlatformInputContext()
|
||||
return;
|
||||
}
|
||||
|
||||
if (env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
|
||||
if (env.jniEnv->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
|
||||
qCritical() << "RegisterNatives failed for '"
|
||||
<< QtNativeInputConnectionClassName
|
||||
<< "'";
|
||||
return;
|
||||
}
|
||||
|
||||
clazz = QtAndroid::findClass(QtExtractedTextClassName, env);
|
||||
clazz = QtAndroid::findClass(QtExtractedTextClassName, env.jniEnv);
|
||||
if (clazz == NULL) {
|
||||
qCritical() << "Native registration unable to find class '"
|
||||
<< QtExtractedTextClassName
|
||||
@ -266,44 +264,44 @@ QAndroidInputContext::QAndroidInputContext():QPlatformInputContext()
|
||||
return;
|
||||
}
|
||||
|
||||
m_extractedTextClass = static_cast<jclass>(env->NewGlobalRef(clazz));
|
||||
m_classConstructorMethodID = env->GetMethodID(m_extractedTextClass, "<init>", "()V");
|
||||
m_extractedTextClass = static_cast<jclass>(env.jniEnv->NewGlobalRef(clazz));
|
||||
m_classConstructorMethodID = env.jniEnv->GetMethodID(m_extractedTextClass, "<init>", "()V");
|
||||
if (m_classConstructorMethodID == NULL) {
|
||||
qCritical() << "GetMethodID failed";
|
||||
return;
|
||||
}
|
||||
|
||||
m_partialEndOffsetFieldID = env->GetFieldID(m_extractedTextClass, "partialEndOffset", "I");
|
||||
m_partialEndOffsetFieldID = env.jniEnv->GetFieldID(m_extractedTextClass, "partialEndOffset", "I");
|
||||
if (m_partialEndOffsetFieldID == NULL) {
|
||||
qCritical() << "Can't find field partialEndOffset";
|
||||
return;
|
||||
}
|
||||
|
||||
m_partialStartOffsetFieldID = env->GetFieldID(m_extractedTextClass, "partialStartOffset", "I");
|
||||
m_partialStartOffsetFieldID = env.jniEnv->GetFieldID(m_extractedTextClass, "partialStartOffset", "I");
|
||||
if (m_partialStartOffsetFieldID == NULL) {
|
||||
qCritical() << "Can't find field partialStartOffset";
|
||||
return;
|
||||
}
|
||||
|
||||
m_selectionEndFieldID = env->GetFieldID(m_extractedTextClass, "selectionEnd", "I");
|
||||
m_selectionEndFieldID = env.jniEnv->GetFieldID(m_extractedTextClass, "selectionEnd", "I");
|
||||
if (m_selectionEndFieldID == NULL) {
|
||||
qCritical() << "Can't find field selectionEnd";
|
||||
return;
|
||||
}
|
||||
|
||||
m_selectionStartFieldID = env->GetFieldID(m_extractedTextClass, "selectionStart", "I");
|
||||
m_selectionStartFieldID = env.jniEnv->GetFieldID(m_extractedTextClass, "selectionStart", "I");
|
||||
if (m_selectionStartFieldID == NULL) {
|
||||
qCritical() << "Can't find field selectionStart";
|
||||
return;
|
||||
}
|
||||
|
||||
m_startOffsetFieldID = env->GetFieldID(m_extractedTextClass, "startOffset", "I");
|
||||
m_startOffsetFieldID = env.jniEnv->GetFieldID(m_extractedTextClass, "startOffset", "I");
|
||||
if (m_startOffsetFieldID == NULL) {
|
||||
qCritical() << "Can't find field startOffset";
|
||||
return;
|
||||
}
|
||||
|
||||
m_textFieldID = env->GetFieldID(m_extractedTextClass, "text", "Ljava/lang/String;");
|
||||
m_textFieldID = env.jniEnv->GetFieldID(m_extractedTextClass, "text", "Ljava/lang/String;");
|
||||
if (m_textFieldID == NULL) {
|
||||
qCritical() << "Can't find field text";
|
||||
return;
|
||||
|
@ -46,29 +46,25 @@
|
||||
|
||||
QAndroidPlatformServices::QAndroidPlatformServices()
|
||||
{
|
||||
JNIEnv *env;
|
||||
if (QtAndroid::javaVM()->AttachCurrentThread(&env, NULL) < 0) {
|
||||
qCritical() << "AttachCurrentThread failed";
|
||||
QtAndroid::AttachedJNIEnv env;
|
||||
if (!env.jniEnv)
|
||||
return;
|
||||
}
|
||||
|
||||
m_openURIMethodID = env->GetStaticMethodID(QtAndroid::applicationClass(),
|
||||
m_openURIMethodID = env.jniEnv->GetStaticMethodID(QtAndroid::applicationClass(),
|
||||
"openURL",
|
||||
"(Ljava/lang/String;)V");
|
||||
}
|
||||
|
||||
bool QAndroidPlatformServices::openUrl(const QUrl &url)
|
||||
{
|
||||
JNIEnv *env;
|
||||
if (QtAndroid::javaVM()->AttachCurrentThread(&env, NULL) < 0) {
|
||||
qCritical() << "AttachCurrentThread failed";
|
||||
QtAndroid::AttachedJNIEnv env;
|
||||
if (!env.jniEnv)
|
||||
return false;
|
||||
}
|
||||
|
||||
jstring string = env->NewString(reinterpret_cast<const jchar *>(url.toString().constData()),
|
||||
jstring string = env.jniEnv->NewString(reinterpret_cast<const jchar *>(url.toString().constData()),
|
||||
url.toString().length());
|
||||
env->CallStaticVoidMethod(QtAndroid::applicationClass(), m_openURIMethodID, string);
|
||||
env->DeleteLocalRef(string);
|
||||
env.jniEnv->CallStaticVoidMethod(QtAndroid::applicationClass(), m_openURIMethodID, string);
|
||||
env.jniEnv->DeleteLocalRef(string);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user