8#include <QtCore/qbytearray.h>
9#include <QtCore/qhash.h>
10#include <QtCore/qreadwritelock.h>
11#include <QtCore/qloggingcategory.h>
18using namespace
Qt::StringLiterals;
288 JNIEnv *env = QJniEnvironment::getJniEnv();
290 env->DeleteGlobalRef(m_jobject);
291 if (m_jclass && m_own_jclass)
292 env->DeleteGlobalRef(m_jclass);
295 template <
typename ...Args>
299 JNIEnv *env = QJniEnvironment::getJniEnv();
301 jmethodID constructorId = QJniObject::getCachedMethodID(env, m_jclass, m_className,
"<init>",
302 signature ? signature :
"()V");
304 jobject
obj =
nullptr;
305 if constexpr (
sizeof...(Args) == 0)
306 obj = env->NewObject(m_jclass, constructorId);
308 obj = env->NewObjectV(m_jclass, constructorId, std::forward<Args>(
args)...);
310 m_jobject = env->NewGlobalRef(
obj);
311 env->DeleteLocalRef(
obj);
318 jobject m_jobject =
nullptr;
319 jclass m_jclass =
nullptr;
320 bool m_own_jclass =
true;
323template <
typename ...Args>
337 return it != cachedClasses->
constEnd() ?
it.value() :
nullptr;
349 if (QJniEnvironment::checkAndClearExceptions(env) || !
object) {
351 env->DeleteLocalRef(
object);
356 env->DeleteLocalRef(
object);
369 if (classNameArray.contains(
'.')) {
370 qWarning(
"QtAndroidPrivate::findClass: className '%s' should use slash separators!",
374 classNameArray.replace(
'.',
'/');
382 const auto &
it = cachedClasses->
constFind(classNameArray);
388 jclass localClazz = env->FindClass(classNameArray.constData());
390 clazz =
static_cast<jclass
>(env->NewGlobalRef(localClazz));
391 env->DeleteLocalRef(localClazz);
395 env->ExceptionClear();
408 jstring classNameObject = env->NewString(
reinterpret_cast<const jchar*
>(binaryClassName.constData()),
409 binaryClassName.length());
411 env->DeleteLocalRef(classNameObject);
413 if (!QJniEnvironment::checkAndClearExceptions(env) && classObject.isValid())
414 clazz =
static_cast<jclass
>(env->NewGlobalRef(classObject.object()));
418 cachedClasses->insert(classNameArray, clazz);
432jmethodID QJniObject::getMethodID(JNIEnv *env,
435 const char *signature,
438 jmethodID
id = isStatic ? env->GetStaticMethodID(clazz,
name, signature)
439 : env->GetMethodID(clazz,
name, signature);
441 if (QJniEnvironment::checkAndClearExceptions(env))
447void QJniObject::callVoidMethodV(JNIEnv *env, jmethodID
id, ...)
const
451 env->CallVoidMethodV(
d->m_jobject,
id,
args);
455jmethodID QJniObject::getCachedMethodID(JNIEnv *env,
459 const char *signature,
463 return getMethodID(env, clazz,
name, signature, isStatic);
481 jmethodID
id = getMethodID(env, clazz,
name, signature, isStatic);
483 cachedMethodID->insert(
key,
id);
488jmethodID QJniObject::getCachedMethodID(JNIEnv *env,
const char *
name,
489 const char *signature,
bool isStatic)
const
491 return QJniObject::getCachedMethodID(env,
d->m_jclass,
d->m_className,
name, signature, isStatic);
498jfieldID QJniObject::getFieldID(JNIEnv *env,
501 const char *signature,
504 jfieldID
id = isStatic ? env->GetStaticFieldID(clazz,
name, signature)
505 : env->GetFieldID(clazz,
name, signature);
507 if (QJniEnvironment::checkAndClearExceptions(env))
513jfieldID QJniObject::getCachedFieldID(JNIEnv *env,
517 const char *signature,
521 return getFieldID(env, clazz,
name, signature, isStatic);
539 jfieldID
id = getFieldID(env, clazz,
name, signature, isStatic);
541 cachedFieldID->insert(
key,
id);
546jfieldID QJniObject::getCachedFieldID(JNIEnv *env,
548 const char *signature,
551 return QJniObject::getCachedFieldID(env,
d->m_jclass,
d->m_className,
name, signature, isStatic);
561QJniObject::QJniObject()
575QJniObject::QJniObject(
const char *
className)
579 d->m_jclass = loadClass(
d->m_className, jniEnv());
580 d->m_own_jclass =
false;
598QJniObject::QJniObject(
const char *
className,
const char *signature, ...)
602 d->m_jclass = loadClass(
d->m_className, jniEnv());
603 d->m_own_jclass =
false;
606 va_start(
args, signature);
607 d->construct(signature,
args);
637QJniObject::QJniObject(jclass clazz,
const char *signature, ...)
641 d->m_jclass =
static_cast<jclass
>(jniEnv()->NewGlobalRef(clazz));
643 va_start(
args, signature);
644 d->construct(signature,
args);
672QJniObject::QJniObject(jclass clazz)
689QJniObject::QJniObject(jobject
object)
695 JNIEnv *env = QJniEnvironment::getJniEnv();
696 d->m_jobject = env->NewGlobalRef(
object);
697 jclass cls = env->GetObjectClass(
object);
698 d->m_jclass =
static_cast<jclass
>(env->NewGlobalRef(cls));
699 env->DeleteLocalRef(cls);
722QJniObject::~QJniObject()
728 if (env->PushLocalFrame(3) != JNI_OK)
731 jmethodID mid = env->GetMethodID(
d->m_jclass,
"getClass",
"()Ljava/lang/Class;");
732 jobject classObject = env->CallObjectMethod(
d->m_jobject, mid);
733 jclass classObjectClass = env->GetObjectClass(classObject);
734 mid = env->GetMethodID(classObjectClass,
"getName",
"()Ljava/lang/String;");
735 jstring stringObject =
static_cast<jstring
>(env->CallObjectMethod(classObject, mid));
736 const jsize
length = env->GetStringUTFLength(stringObject);
737 const char* nameString = env->GetStringUTFChars(stringObject, NULL);
739 env->ReleaseStringUTFChars(stringObject, nameString);
740 env->PopLocalFrame(
nullptr);
749JNIEnv *QJniObject::jniEnv() const noexcept
751 return QJniEnvironment::getJniEnv();
774jobject QJniObject::object()
const
792jclass QJniObject::objectClass()
const
806 if (
d->m_className.isEmpty() &&
d->m_jclass &&
d->m_jobject) {
807 JNIEnv *env = jniEnv();
808 d->m_className = getClassNameHelper(env,
d.get());
810 return d->m_className;
955QJniObject QJniObject::callObjectMethod(
const char *
methodName,
const char *signature, ...)
const
957 jmethodID
id = getCachedMethodID(jniEnv(),
methodName, signature);
960 va_start(
args, signature);
983 const char *signature, ...)
985 JNIEnv *env = QJniEnvironment::getJniEnv();
986 jclass clazz = QJniObject::loadClass(
className, env);
988 jmethodID
id = QJniObject::getCachedMethodID(env, clazz,
993 va_start(
args, signature);
1010 const char *signature, ...)
1014 jmethodID
id = getMethodID(env.jniEnv(), clazz,
methodName, signature,
true);
1017 va_start(
args, signature);
1042QJniObject QJniObject::callStaticObjectMethod(jclass clazz, jmethodID methodId, ...)
1044 if (clazz && methodId) {
1047 va_start(
args, methodId);
1179 const char *fieldName,
1180 const char *signature)
1182 JNIEnv *env = QJniEnvironment::getJniEnv();
1183 jclass clazz = QJniObject::loadClass(
className, env);
1186 jfieldID
id = QJniObject::getCachedFieldID(env, clazz,
1208QJniObject QJniObject::getStaticObjectField(jclass clazz,
const char *fieldName,
1209 const char *signature)
1211 JNIEnv *env = QJniEnvironment::getJniEnv();
1212 jfieldID
id = getFieldID(env, clazz, fieldName, signature,
true);
1250QJniObject QJniObject::getObjectField(
const char *fieldName,
const char *signature)
const
1252 jfieldID
id = getCachedFieldID(jniEnv(), fieldName, signature);
1307 jstring stringRef = env->NewString(
reinterpret_cast<const jchar*
>(
string.constData()),
1310 stringObject.d->m_className =
"java/lang/String";
1311 return stringObject;
1328QString QJniObject::toString()
const
1333 QJniObject string = callObjectMethod<jstring>(
"toString");
1334 const int strLength =
string.jniEnv()->GetStringLength(
string.object<jstring>());
1336 string.jniEnv()->GetStringRegion(
string.object<jstring>(), 0, strLength,
reinterpret_cast<jchar *
>(
res.data()));
1351bool QJniObject::isClassAvailable(
const char *
className)
1358 return loadClass(
className, env.jniEnv());
1372bool QJniObject::isValid()
const
1374 return d->m_jobject;
1391QJniObject QJniObject::fromLocalRef(jobject lref)
1394 obj.jniEnv()->DeleteLocalRef(lref);
1398bool QJniObject::isSameObject(jobject
obj)
const
1400 if (
d->m_jobject ==
obj)
1402 if (!
d->m_jobject || !
obj)
1404 return jniEnv()->IsSameObject(
d->m_jobject,
obj);
1409 return isSameObject(
other.d->m_jobject);
1412void QJniObject::assign(jobject
obj)
1414 if (
d && isSameObject(
obj))
1419 JNIEnv *env = QJniEnvironment::getJniEnv();
1420 d->m_jobject = env->NewGlobalRef(
obj);
1421 jclass objectClass = env->GetObjectClass(
obj);
1422 d->m_jclass =
static_cast<jclass
>(env->NewGlobalRef(objectClass));
1423 env->DeleteLocalRef(objectClass);
1427jobject QJniObject::javaObject()
const
1429 return d->m_jobject;
static QByteArray fromRawData(const char *data, qsizetype size)
Constructs a QByteArray that uses the first size bytes of the data array.
void construct(const char *signature=nullptr, Args &&...args)
const_iterator constEnd() const noexcept
const_iterator constFind(const T &value) const
static QSharedPointer create(Args &&...arguments)
This is an overloaded member function, provided for convenience. It differs from the above function o...
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QSet< QString >::iterator it
Combined button and popup list for selecting options.
Q_CORE_EXPORT jclass findClass(const char *className, JNIEnv *env)
constexpr Initialization Uninitialized
static QString methodName(const QDBusIntrospection::Method &method)
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
static QByteArray cacheKey(Args &&...args)
QHash< QByteArray, jmethodID > JMethodIDHash
QHash< QByteArray, jclass > JClassHash
static jclass getCachedClass(const QByteArray &className)
static QJniObject getCleanJniObject(jobject object, JNIEnv *env)
QHash< QByteArray, jfieldID > JFieldIDHash
#define Q_LOGGING_CATEGORY(name,...)
GLenum GLuint GLenum GLsizei length
const char className[16]
[1]