7#include <QtCore/qsharedpointer.h>
9#if defined(Q_QDOC) || defined(Q_OS_ANDROID)
11#include <QtCore/qjnienvironment.h>
12#include <QtCore/qxptype_traits.h>
16class QJniObjectPrivate;
24template <
typename T,
typename =
void>
struct StoresGlobalRefTest : std::false_type {};
26struct StoresGlobalRefTest<T, std::void_t<
decltype(std::declval<T>().object())>>
27 : std::is_same<
decltype(std::declval<T>().object()), jobject>
31template <
typename R,
typename =
void>
32struct CallerHandlesException : std::false_type {
36struct CallerHandlesException<R, std::void_t<
typename R::unexpected_type,
37 typename R::value_type,
38 typename R::error_type>> : std::true_type
40 using value_type =
typename R::value_type;
43template <
typename ReturnType>
44static constexpr bool callerHandlesException = CallerHandlesException<ReturnType>::value;
46template <
typename ...Args>
50 bool hasFrame =
false;
52 explicit LocalFrame(JNIEnv *env =
nullptr)
noexcept
59 env->PopLocalFrame(
nullptr);
64 hasFrame = jniEnv()->PushLocalFrame(
sizeof...(Args)) == 0;
67 JNIEnv *jniEnv()
const
70 env = QJniEnvironment::getJniEnv();
75 auto convertToJni(T &&value)
77 using Type = q20::remove_cvref_t<T>;
78 using ResultType =
decltype(QtJniTypes::Traits<Type>::convertToJni(jniEnv(),
79 std::declval<T&&>()));
80 if constexpr (std::is_base_of_v<std::remove_pointer_t<jobject>,
81 std::remove_pointer_t<ResultType>>) {
84 if constexpr (!qxp::is_detected_v<StoresGlobalRefTest, Type>) {
89 return QtJniTypes::Traits<Type>::convertToJni(jniEnv(), std::forward<T>(value));
92 auto convertFromJni(QJniObject &&object)
94 using Type = q20::remove_cvref_t<T>;
95 return QtJniTypes::Traits<Type>::convertFromJni(std::move(object));
99template <
typename Ret,
typename ...Args>
100struct LocalFrameWithReturn : LocalFrame<Args...>
102 using ReturnType = Ret;
104 using LocalFrame<Args...>::LocalFrame;
106 template <
typename T>
107 auto convertFromJni(QJniObject &&object)
109 return LocalFrame<Args...>::
template convertFromJni<T>(std::move(object));
112 template <
typename T>
113 auto convertFromJni(jobject object);
115 bool checkAndClearExceptions()
const
117 if constexpr (callerHandlesException<ReturnType>)
120 return QJniEnvironment::checkAndClearExceptions(
this->jniEnv());
125 if constexpr (callerHandlesException<ReturnType>) {
126 JNIEnv *env =
this->jniEnv();
127 if (env->ExceptionCheck()) {
128 jthrowable exception = env->ExceptionOccurred();
129 env->ExceptionClear();
130 return ReturnType(
typename ReturnType::unexpected_type(exception));
134 checkAndClearExceptions();
138 template <
typename Value>
139 auto makeResult(Value &&value)
141 if constexpr (callerHandlesException<ReturnType>) {
142 auto maybeValue = makeResult();
144 return ReturnType(std::forward<Value>(value));
145 return std::move(maybeValue);
147 checkAndClearExceptions();
148 return std::forward<Value>(value);
155class Q_CORE_EXPORT QJniObject
157 template <
typename Ret,
typename ...Args>
using LocalFrame
158 = QtJniTypes::Detail::LocalFrameWithReturn<Ret, Args...>;
162 explicit QJniObject(
const char *className);
163 explicit QJniObject(
const char *className,
const char *signature, ...);
164 template<
typename ...Args
166 , std::enable_if_t<!std::disjunction_v<QtJniTypes::IsStringType<std::decay_t<Args>>...>>* =
nullptr
169 explicit QJniObject(
const char *className, Args &&...args)
170 : QJniObject(QtJniTypes::Detail::LocalFrame<Args...>{}, className, std::forward<Args>(args)...)
174 template<
typename ...Args>
175 explicit QJniObject(QtJniTypes::Detail::LocalFrame<Args...> localFrame,
const char *className, Args &&...args)
176 : QJniObject(className, QtJniTypes::constructorSignature<Args...>().data(),
177 localFrame.convertToJni(std::forward<Args>(args))...)
181 explicit QJniObject(jclass clazz);
182 explicit QJniObject(jclass clazz,
const char *signature, ...);
183 template<
typename ...Args
185 , std::enable_if_t<!std::disjunction_v<QtJniTypes::IsStringType<std::decay_t<Args>>...>>* =
nullptr
188 explicit QJniObject(jclass clazz, Args &&...args)
189 : QJniObject(clazz, QtJniTypes::constructorSignature<Args...>().data(),
190 std::forward<Args>(args)...)
192 QJniObject(jobject globalRef);
194 QJniObject(
const QJniObject &other)
noexcept =
default;
195 QJniObject(QJniObject &&other)
noexcept =
default;
196 QJniObject &operator=(
const QJniObject &other)
noexcept =
default;
197 QJniObject &operator=(QJniObject &&other)
noexcept =
default;
201 void swap(QJniObject &other)
noexcept { d.swap(other.d); }
203 template<
typename Class,
typename ...Args
205 , QtJniTypes::IfValidSignatureTypes<Class, Args...> =
true
208 static inline auto construct(Args &&...args)
210 LocalFrame<Class, Args...> frame;
211 jclass clazz = QJniObject::loadClassKeepExceptions(QtJniTypes::Traits<Class>::className().data(),
214 ? QJniObject(clazz, QtJniTypes::constructorSignature<Args...>().data(),
215 frame.convertToJni(std::forward<Args>(args))...)
216 : QtJniTypes::Detail::callerHandlesException<Class>
217 ? QJniObject(Qt::Initialization::Uninitialized)
219 return frame.makeResult(std::move(res));
222 jobject object()
const;
223 template <
typename T> T object()
const
225 QtJniTypes::assertObjectType<T>();
226 return static_cast<T>(javaObject());
229 jclass objectClass()
const;
230 QByteArray className()
const;
232 template <
typename ReturnType =
void,
typename ...Args
234 , QtJniTypes::IfValidFieldType<ReturnType> =
true
237 auto callMethod(
const char *methodName,
const char *signature, Args &&...args)
const
239 using Ret =
typename QtJniTypes::Detail::CallerHandlesException<ReturnType>::value_type;
240 LocalFrame<ReturnType, Args...> frame(jniEnv());
241 jmethodID id = getCachedMethodID(frame.jniEnv(), methodName, signature);
243 if constexpr (QtJniTypes::isObjectType<Ret>()) {
244 return frame.makeResult(frame.
template convertFromJni<Ret>(callObjectMethodImpl(
245 id, frame.convertToJni(std::forward<Args>(args))...))
249 if constexpr (std::is_same_v<Ret,
void>) {
250 callVoidMethodV(frame.jniEnv(), id,
251 frame.convertToJni(std::forward<Args>(args))...);
254 callMethodForType<Ret>(frame.jniEnv(), res, object(), id,
255 frame.convertToJni(std::forward<Args>(args))...);
256 return frame.makeResult(res);
259 if constexpr (!std::is_same_v<Ret,
void>)
260 return frame.makeResult(Ret{});
262 return frame.makeResult();
266 template <
typename ReturnType =
void,
typename ...Args
268 , QtJniTypes::IfValidSignatureTypes<ReturnType, Args...> =
true
271 auto callMethod(
const char *methodName, Args &&...args)
const
273 constexpr auto signature = QtJniTypes::methodSignature<ReturnType, Args...>();
274 return callMethod<ReturnType>(methodName, signature.data(), std::forward<Args>(args)...);
277 template <
typename Ret,
typename ...Args
279 , QtJniTypes::IfValidSignatureTypes<Ret, Args...> =
true
282 QJniObject callObjectMethod(
const char *methodName, Args &&...args)
const
284 QtJniTypes::assertObjectType<Ret>();
285 constexpr auto signature = QtJniTypes::methodSignature<Ret, Args...>();
286 LocalFrame<Ret, Args...> frame(jniEnv());
287 auto object = frame.
template convertFromJni<Ret>(callObjectMethod(methodName, signature,
288 frame.convertToJni(std::forward<Args>(args))...));
289 frame.checkAndClearExceptions();
293 QJniObject callObjectMethod(
const char *methodName,
const char *signature, ...)
const;
295 template <
typename Ret =
void,
typename ...Args>
296 static auto callStaticMethod(
const char *className,
const char *methodName,
const char *signature, Args &&...args)
298 LocalFrame<Ret, Args...> frame;
299 jclass clazz = QJniObject::loadClass(className, frame.jniEnv());
300 return callStaticMethod<Ret>(clazz, methodName, signature, std::forward<Args>(args)...);
303 template <
typename Ret =
void,
typename ...Args>
304 static auto callStaticMethod(jclass clazz,
const char *methodName,
const char *signature, Args &&...args)
306 LocalFrame<Ret, Args...> frame;
307 jmethodID id = clazz ? getMethodID(frame.jniEnv(), clazz, methodName, signature,
true)
309 return callStaticMethod<Ret>(clazz, id, std::forward<Args>(args)...);
312 template <
typename ReturnType =
void,
typename ...Args
314 , QtJniTypes::IfValidFieldType<ReturnType> =
true
317 static auto callStaticMethod(jclass clazz, jmethodID methodId, Args &&...args)
319 using Ret =
typename QtJniTypes::Detail::CallerHandlesException<ReturnType>::value_type;
320 LocalFrame<ReturnType, Args...> frame;
321 if constexpr (QtJniTypes::isObjectType<Ret>()) {
322 return frame.makeResult(frame.
template convertFromJni<Ret>(callStaticObjectMethod(
324 frame.convertToJni(std::forward<Args>(args))...))
327 if (clazz && methodId) {
328 if constexpr (std::is_same_v<Ret,
void>) {
329 callStaticMethodForVoid(frame.jniEnv(), clazz, methodId,
330 frame.convertToJni(std::forward<Args>(args))...);
333 callStaticMethodForType<Ret>(frame.jniEnv(), res, clazz, methodId,
334 frame.convertToJni(std::forward<Args>(args))...);
335 return frame.makeResult(res);
338 if constexpr (!std::is_same_v<Ret,
void>)
339 return frame.makeResult(Ret{});
341 return frame.makeResult();
345 template <
typename ReturnType =
void,
typename ...Args
347 , QtJniTypes::IfValidSignatureTypes<ReturnType, Args...> =
true
350 static auto callStaticMethod(
const char *className,
const char *methodName, Args &&...args)
352 using Ret =
typename QtJniTypes::Detail::CallerHandlesException<ReturnType>::value_type;
353 LocalFrame<Ret, Args...> frame;
354 jclass clazz = QJniObject::loadClass(className, frame.jniEnv());
355 const jmethodID id = clazz ? getMethodID(frame.jniEnv(), clazz, methodName,
356 QtJniTypes::methodSignature<Ret, Args...>().data(),
true)
358 return callStaticMethod<ReturnType>(clazz, id, std::forward<Args>(args)...);
361 template <
typename ReturnType =
void,
typename ...Args
363 , QtJniTypes::IfValidSignatureTypes<ReturnType, Args...> =
true
366 static auto callStaticMethod(jclass clazz,
const char *methodName, Args &&...args)
368 constexpr auto signature = QtJniTypes::methodSignature<ReturnType, Args...>();
369 return callStaticMethod<ReturnType>(clazz, methodName, signature.data(), std::forward<Args>(args)...);
371 template <
typename Klass,
typename ReturnType =
void,
typename ...Args
373 , QtJniTypes::IfValidSignatureTypes<ReturnType, Args...> =
true
376 static auto callStaticMethod(
const char *methodName, Args &&...args)
378 LocalFrame<ReturnType, Args...> frame;
379 const jclass clazz = QJniObject::loadClass(QtJniTypes::Traits<Klass>::className().data(),
381 const jmethodID id = clazz ? getMethodID(frame.jniEnv(), clazz, methodName,
382 QtJniTypes::methodSignature<ReturnType, Args...>().data(),
true)
384 return callStaticMethod<ReturnType>(clazz, id, std::forward<Args>(args)...);
387 static QJniObject callStaticObjectMethod(
const char *className,
const char *methodName,
388 const char *signature, ...);
390 static QJniObject callStaticObjectMethod(jclass clazz,
const char *methodName,
391 const char *signature, ...);
393 static QJniObject callStaticObjectMethod(jclass clazz, jmethodID methodId, ...);
396 template <
typename Ret,
typename ...Args
398 , QtJniTypes::IfValidSignatureTypes<Ret, Args...> =
true
401 static QJniObject callStaticObjectMethod(
const char *className,
const char *methodName, Args &&...args)
403 QtJniTypes::assertObjectType<Ret>();
404 constexpr auto signature = QtJniTypes::methodSignature<Ret, Args...>();
405 LocalFrame<QJniObject, Args...> frame;
406 return frame.
template convertFromJni<Ret>(callStaticObjectMethod(className, methodName, signature.data(),
407 frame.convertToJni(std::forward<Args>(args))...));
410 template <
typename Ret,
typename ...Args
412 , QtJniTypes::IfValidSignatureTypes<Ret, Args...> =
true
415 static QJniObject callStaticObjectMethod(jclass clazz,
const char *methodName, Args &&...args)
417 QtJniTypes::assertObjectType<Ret>();
418 constexpr auto signature = QtJniTypes::methodSignature<Ret, Args...>();
419 LocalFrame<QJniObject, Args...> frame;
420 return frame.
template convertFromJni<Ret>(callStaticObjectMethod(clazz, methodName, signature.data(),
421 frame.convertToJni(std::forward<Args>(args))...));
424 template <
typename Type
426 , QtJniTypes::IfValidFieldType<Type> =
true
429 auto getField(
const char *fieldName)
const
431 using T =
typename QtJniTypes::Detail::CallerHandlesException<Type>::value_type;
432 LocalFrame<Type, T> frame(jniEnv());
433 constexpr auto signature = QtJniTypes::fieldSignature<T>();
434 jfieldID id = getCachedFieldID(frame.jniEnv(), fieldName, signature);
436 if constexpr (QtJniTypes::isObjectType<T>()) {
437 return frame.makeResult(frame.
template convertFromJni<T>(getObjectFieldImpl(
443 getFieldForType<T>(frame.jniEnv(), res, object(), id);
444 return frame.makeResult(res);
448 template <
typename Klass,
typename T
450 , QtJniTypes::IfValidFieldType<T> =
true
453 static auto getStaticField(
const char *fieldName)
455 return getStaticField<T>(QtJniTypes::Traits<Klass>::className(), fieldName);
460 , std::enable_if_t<QtJniTypes::isObjectType<T>(),
bool> =
true
463 QJniObject getObjectField(
const char *fieldName)
const
465 constexpr auto signature = QtJniTypes::fieldSignature<T>();
466 return getObjectField(fieldName, signature);
469 QJniObject getObjectField(
const char *fieldName,
const char *signature)
const;
471 template <
typename Type
473 , QtJniTypes::IfValidFieldType<Type> =
true
476 static auto getStaticField(
const char *className,
const char *fieldName)
478 using T =
typename QtJniTypes::Detail::CallerHandlesException<Type>::value_type;
479 LocalFrame<Type, T> frame;
480 jclass clazz = QJniObject::loadClass(className, frame.jniEnv());
481 return getStaticField<Type>(clazz, fieldName);
484 template <
typename Type
486 , QtJniTypes::IfValidFieldType<Type> =
true
489 static auto getStaticField(jclass clazz,
const char *fieldName)
491 using T =
typename QtJniTypes::Detail::CallerHandlesException<Type>::value_type;
492 LocalFrame<Type, T> frame;
493 constexpr auto signature = QtJniTypes::fieldSignature<T>();
494 jfieldID id = clazz ? getFieldID(frame.jniEnv(), clazz, fieldName, signature,
true)
496 if constexpr (QtJniTypes::isObjectType<T>()) {
497 return frame.makeResult(frame.
template convertFromJni<T>(getStaticObjectFieldImpl(
498 frame.jniEnv(), clazz, id))
503 getStaticFieldForType<T>(frame.jniEnv(), res, clazz, id);
504 return frame.makeResult(res);
510 , std::enable_if_t<QtJniTypes::isObjectType<T>(),
bool> =
true
513 static QJniObject getStaticObjectField(
const char *className,
const char *fieldName)
515 constexpr auto signature = QtJniTypes::fieldSignature<T>();
516 return getStaticObjectField(className, fieldName, signature);
519 static QJniObject getStaticObjectField(
const char *className,
520 const char *fieldName,
521 const char *signature);
525 , std::enable_if_t<QtJniTypes::isObjectType<T>(),
bool> =
true
528 static QJniObject getStaticObjectField(jclass clazz,
const char *fieldName)
530 constexpr auto signature = QtJniTypes::fieldSignature<T>();
531 return getStaticObjectField(clazz, fieldName, signature);
534 static QJniObject getStaticObjectField(jclass clazz,
const char *fieldName,
535 const char *signature);
537 template <
typename Ret =
void,
typename Type
539 , QtJniTypes::IfValidFieldType<Type> =
true
542 auto setField(
const char *fieldName, Type value)
545 using T = std::conditional_t<std::is_void_v<Ret> || QtJniTypes::Detail::callerHandlesException<Ret>,
547 LocalFrame<Ret, T> frame(jniEnv());
548 constexpr auto signature = QtJniTypes::fieldSignature<T>();
549 jfieldID id = getCachedFieldID(jniEnv(), fieldName, signature);
551 setFieldForType<T>(jniEnv(), object(), id, value);
552 return frame.makeResult();
555 template <
typename Ret =
void,
typename Type
557 , QtJniTypes::IfValidFieldType<Type> =
true
560 auto setField(
const char *fieldName,
const char *signature, Type value)
563 using T = std::conditional_t<std::is_void_v<Ret> || QtJniTypes::Detail::callerHandlesException<Ret>,
565 LocalFrame<Ret, T> frame(jniEnv());
566 jfieldID id = getCachedFieldID(frame.jniEnv(), fieldName, signature);
568 setFieldForType<T>(jniEnv(), object(), id, value);
569 return frame.makeResult();
572 template <
typename Ret =
void,
typename Type
574 , QtJniTypes::IfValidFieldType<Type> =
true
577 static auto setStaticField(
const char *className,
const char *fieldName, Type value)
580 using T = std::conditional_t<std::is_void_v<Ret> || QtJniTypes::Detail::callerHandlesException<Ret>,
582 LocalFrame<Ret, T> frame;
583 if (jclass clazz = QJniObject::loadClass(className, frame.jniEnv())) {
584 constexpr auto signature = QtJniTypes::fieldSignature<q20::remove_cvref_t<T>>();
585 jfieldID id = getCachedFieldID(frame.jniEnv(), clazz, className, fieldName,
588 setStaticFieldForType<T>(frame.jniEnv(), clazz, id, value);
590 return frame.makeResult();
593 template <
typename Ret =
void,
typename Type
595 , QtJniTypes::IfValidFieldType<Type> =
true
598 static auto setStaticField(
const char *className,
const char *fieldName,
599 const char *signature, Type value)
602 using T = std::conditional_t<std::is_void_v<Ret> || QtJniTypes::Detail::callerHandlesException<Ret>,
604 LocalFrame<Ret, T> frame;
605 if (jclass clazz = QJniObject::loadClass(className, frame.jniEnv())) {
606 jfieldID id = getCachedFieldID(frame.jniEnv(), clazz, className, fieldName,
609 setStaticFieldForType<T>(frame.jniEnv(), clazz, id, value);
611 return frame.makeResult();
614 template <
typename Ret =
void,
typename Type
616 , QtJniTypes::IfValidFieldType<Type> =
true
619 static auto setStaticField(jclass clazz,
const char *fieldName,
620 const char *signature, Type value)
623 using T = std::conditional_t<std::is_void_v<Ret> || QtJniTypes::Detail::callerHandlesException<Ret>,
625 LocalFrame<Ret, T> frame;
626 jfieldID id = getFieldID(frame.jniEnv(), clazz, fieldName, signature,
true);
629 setStaticFieldForType<T>(frame.jniEnv(), clazz, id, value);
630 return frame.makeResult();
633 template <
typename Ret =
void,
typename Type
635 , QtJniTypes::IfValidFieldType<Type> =
true
638 static auto setStaticField(jclass clazz,
const char *fieldName, Type value)
640 return setStaticField<Ret, Type>(clazz, fieldName,
641 QtJniTypes::fieldSignature<q20::remove_cvref_t<Type>>(),
645 template <
typename Klass,
typename Ret =
void,
typename Type
647 , QtJniTypes::IfValidFieldType<Type> =
true
650 static auto setStaticField(
const char *fieldName, Type value)
652 return setStaticField<Ret, Type>(QtJniTypes::Traits<Klass>::className(), fieldName, value);
655 static QJniObject fromString(
const QString &string);
656 QString toString()
const;
658 static bool isClassAvailable(
const char *className);
659 bool isValid()
const;
662 static QJniObject fromLocalRef(jobject lref);
664 template <
typename T,
665 std::enable_if_t<std::is_convertible_v<T, jobject>,
bool> =
true>
666 QJniObject &operator=(T obj)
668 assign(
static_cast<T>(obj));
673 QJniObject(Qt::Initialization) {}
674 JNIEnv *jniEnv()
const noexcept;
677 static jclass loadClass(
const QByteArray &className, JNIEnv *env);
678 static jclass loadClassKeepExceptions(
const QByteArray &className, JNIEnv *env);
680#if QT_CORE_REMOVED_SINCE(6
, 7
)
682 static jclass loadClass(
const QByteArray &className, JNIEnv *env,
bool binEncoded);
683 static QByteArray toBinaryEncClassName(
const QByteArray &className);
684 void callVoidMethodV(JNIEnv *env, jmethodID id, va_list args)
const;
687 static jfieldID getCachedFieldID(JNIEnv *env, jclass clazz,
const QByteArray &className,
688 const char *name,
const char *signature,
689 bool isStatic =
false);
690 jfieldID getCachedFieldID(JNIEnv *env,
const char *name,
const char *signature,
691 bool isStatic =
false)
const;
692 static jmethodID getCachedMethodID(JNIEnv *env, jclass clazz,
const QByteArray &className,
693 const char *name,
const char *signature,
694 bool isStatic =
false);
695 jmethodID getCachedMethodID(JNIEnv *env,
const char *name,
const char *signature,
696 bool isStatic =
false)
const;
698 static jfieldID getFieldID(JNIEnv *env, jclass clazz,
const char *name,
699 const char *signature,
bool isStatic =
false);
700 static jmethodID getMethodID(JNIEnv *env, jclass clazz,
const char *name,
701 const char *signature,
bool isStatic =
false);
703 void callVoidMethodV(JNIEnv *env, jmethodID id, ...)
const;
705 bool isSameObject(jobject obj)
const;
706 bool isSameObject(
const QJniObject &other)
const;
707 void assign(jobject obj);
708 jobject javaObject()
const;
710 friend bool operator==(
const QJniObject &,
const QJniObject &);
711 friend bool operator!=(
const QJniObject&,
const QJniObject&);
714 static constexpr void callMethodForType(JNIEnv *env, T &res, jobject obj, jmethodID id, ...)
721 QtJniTypes::Caller<T>::callMethodForType(env, res, obj, id, args);
725 jobject callObjectMethodImpl(jmethodID method, ...)
const
728 va_start(args, method);
729 jobject res = method ? jniEnv()->CallObjectMethodV(javaObject(), method, args)
736 static constexpr void callStaticMethodForType(JNIEnv *env, T &res, jclass clazz,
743 QtJniTypes::Caller<T>::callStaticMethodForType(env, res, clazz, id, args);
747 static void callStaticMethodForVoid(JNIEnv *env, jclass clazz, jmethodID id, ...)
753 env->CallStaticVoidMethodV(clazz, id, args);
759 static constexpr void getFieldForType(JNIEnv *env, T &res, jobject obj, jfieldID id)
764 QtJniTypes::Caller<T>::getFieldForType(env, res, obj, id);
768 static constexpr void getStaticFieldForType(JNIEnv *env, T &res, jclass clazz, jfieldID id)
770 QtJniTypes::Caller<T>::getStaticFieldForType(env, res, clazz, id);
773 template<
typename Type>
774 static constexpr void setFieldForType(JNIEnv *env, jobject obj, jfieldID id, Type value)
779 using T = q20::remove_cvref_t<Type>;
780 if constexpr (QtJniTypes::isObjectType<T>()) {
781 LocalFrame<T, T> frame(env);
782 env->SetObjectField(obj, id,
static_cast<jobject>(frame.convertToJni(value)));
784 using ValueType =
typename QtJniTypes::Detail::CallerHandlesException<T>::value_type;
785 QtJniTypes::Caller<ValueType>::setFieldForType(env, obj, id, value);
789 jobject getObjectFieldImpl(JNIEnv *env, jfieldID field)
const
791 return field ? env->GetObjectField(javaObject(), field) :
nullptr;
794 static jobject getStaticObjectFieldImpl(JNIEnv *env, jclass clazz, jfieldID field)
796 return clazz && field ? env->GetStaticObjectField(clazz, field)
800 template<
typename Type>
801 static constexpr void setStaticFieldForType(JNIEnv *env, jclass clazz, jfieldID id, Type value)
806 using T = q20::remove_cvref_t<Type>;
807 if constexpr (QtJniTypes::isObjectType<T>()) {
808 LocalFrame<T, T> frame(env);
809 env->SetStaticObjectField(clazz, id,
static_cast<jobject>(frame.convertToJni(value)));
811 QtJniTypes::Caller<T>::setStaticFieldForType(env, clazz, id, value);
815 friend QJniObjectPrivate;
816 QSharedPointer<QJniObjectPrivate> d;
819inline bool operator==(
const QJniObject &obj1,
const QJniObject &obj2)
821 return obj1.isSameObject(obj2);
824inline bool operator!=(
const QJniObject &obj1,
const QJniObject &obj2)
826 return !obj1.isSameObject(obj2);
829namespace QtJniTypes {
832 operator QJniObject()
const {
return m_object; }
834 bool isValid()
const {
return m_object.isValid(); }
835 jclass objectClass()
const {
return m_object.objectClass(); }
836 QString toString()
const {
return m_object.toString(); }
838 template <
typename T = jobject>
840 return m_object.object<T>();
844 JObjectBase() =
default;
845 JObjectBase(
const JObjectBase &) =
default;
846 JObjectBase(JObjectBase &&) =
default;
847 JObjectBase &operator=(
const JObjectBase &) =
default;
848 JObjectBase &operator=(JObjectBase &&) =
default;
849 ~JObjectBase() =
default;
851 Q_IMPLICIT JObjectBase(jobject object) : m_object(object) {}
852 Q_IMPLICIT JObjectBase(
const QJniObject &object) : m_object(object) {}
853 Q_IMPLICIT JObjectBase(QJniObject &&object)
noexcept : m_object(std::move(object)) {}
858template<
typename Type>
859class JObject :
public JObjectBase
865 : JObjectBase{QJniObject(QtJniTypes::Traits<Class>::className())}
867 Q_IMPLICIT JObject(jobject object) : JObjectBase(object) {}
868 Q_IMPLICIT JObject(
const QJniObject &object) : JObjectBase(object) {}
869 Q_IMPLICIT JObject(QJniObject &&object)
noexcept : JObjectBase(std::move(object)) {}
872 JObject(
const JObject &other) =
default;
873 JObject(JObject &&other)
noexcept =
default;
874 JObject &operator=(
const JObject &other) =
default;
875 JObject &operator=(JObject &&other)
noexcept =
default;
877 ~JObject() =
default;
879 template<
typename Arg,
typename ...Args
880 , std::enable_if_t<!std::is_same_v<q20::remove_cvref_t<Arg>, JObject>,
bool> =
true
881 , IfValidSignatureTypes<Arg, Args...> =
true
883 explicit JObject(Arg && arg, Args &&...args)
884 : JObjectBase{QJniObject(QtJniTypes::Traits<Class>::className(),
885 std::forward<Arg>(arg), std::forward<Args>(args)...)}
889 static JObject fromJObject(jobject object)
891 return JObject(object);
893 template <
typename ...Args>
894 static JObject construct(Args &&...args)
896 return JObject(std::forward<Args>(args)...);
898 static JObject fromLocalRef(jobject lref)
900 return JObject(QJniObject::fromLocalRef(lref));
904 bool isValid()
const;
905 jclass objectClass()
const;
906 QString toString()
const;
907 template <
typename T = jobject> object()
const;
910 static bool registerNativeMethods(std::initializer_list<JNINativeMethod> methods)
913 return env.registerNativeMethods<Class>(methods);
917 template <
typename Ret =
void,
typename ...Args
919 , QtJniTypes::IfValidSignatureTypes<Ret, Args...> =
true
922 static auto callStaticMethod(
const char *name, Args &&...args)
924 return QJniObject::callStaticMethod<Class, Ret, Args...>(name,
925 std::forward<Args>(args)...);
929 , QtJniTypes::IfValidFieldType<T> =
true
932 static auto getStaticField(
const char *field)
934 return QJniObject::getStaticField<Class, T>(field);
936 template <
typename Ret =
void,
typename T
938 , QtJniTypes::IfValidFieldType<T> =
true
941 static auto setStaticField(
const char *field, T &&value)
943 return QJniObject::setStaticField<Class, Ret, T>(field, std::forward<T>(value));
947 template <
typename Ret =
void,
typename ...Args
949 , QtJniTypes::IfValidSignatureTypes<Ret, Args...> =
true
952 auto callMethod(
const char *method, Args &&...args)
const
954 return m_object.callMethod<Ret>(method, std::forward<Args>(args)...);
958 , QtJniTypes::IfValidFieldType<T> =
true
961 auto getField(
const char *fieldName)
const
963 return m_object.getField<T>(fieldName);
966 template <
typename Ret =
void,
typename T
968 , QtJniTypes::IfValidFieldType<T> =
true
971 auto setField(
const char *fieldName, T &&value)
973 return m_object.setField<Ret>(fieldName, std::forward<T>(value));
976 QByteArray className()
const {
977 return QtJniTypes::Traits<Class>::className().data();
980 static bool isClassAvailable()
982 return QJniObject::isClassAvailable(QtJniTypes::Traits<Class>::className().data());
986 friend bool comparesEqual(
const JObject &lhs,
const JObject &rhs)
987 {
return lhs.m_object == rhs.m_object; }
988 Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(JObject);
991template <
typename T>
struct Traits<JObject<T>> {
992 static constexpr auto signature() {
return Traits<T>::signature(); }
993 static constexpr auto className() {
return Traits<T>::className(); }
994 static auto convertToJni(JNIEnv *,
const JObject<T> &value)
996 return value.object();
998 static auto convertFromJni(QJniObject &&object)
1000 return JObject<T>(std::move(object));
1005struct Traits<QJniObject>
1007 static constexpr auto className()
1009 return CTString(
"java/lang/Object");
1012 static constexpr auto signature()
1014 return CTString(
"Ljava/lang/Object;");
1017 static auto convertToJni(JNIEnv *,
const QJniObject &value)
1019 return value.object();
1021 static auto convertFromJni(QJniObject &&object)
1023 return std::move(object);
1028struct Traits<QString>
1030 static constexpr auto className()
1032 return CTString(
"java/lang/String");
1034 static constexpr auto signature()
1036 return CTString(
"Ljava/lang/String;");
1039 static auto convertToJni(JNIEnv *env,
const QString &value)
1041 return QtJniTypes::Detail::fromQString(value, env);
1044 static auto convertFromJni(QJniObject &&object)
1046 return object.toString();
1050template <
typename T>
1051struct Traits<T, std::enable_if_t<QtJniTypes::Detail::callerHandlesException<T>>>
1053 static constexpr auto className()
1055 return Traits<
typename T::value_type>::className();
1058 static constexpr auto signature()
1060 return Traits<
typename T::value_type>::signature();
1066template <
typename ReturnType,
typename ...Args>
1067template <
typename T>
1068auto QtJniTypes::Detail::LocalFrameWithReturn<ReturnType, Args...>::convertFromJni(jobject object)
1076 if constexpr (callerHandlesException<ReturnType> &&
1077 std::is_base_of_v<std::remove_pointer_t<jobject>, std::remove_pointer_t<T>>)
1078 return static_cast<T>(object);
1080 return convertFromJni<T>(object ? QJniObject::fromLocalRef(object) : QJniObject());
\preliminary \inmodule QtCorePrivate
Q_CORE_EXPORT void unregisterNewIntentListener(NewIntentListener *listener)
Q_CORE_EXPORT int acuqireServiceSetup(int flags)
Q_CORE_EXPORT void registerNewIntentListener(NewIntentListener *listener)
Q_CORE_EXPORT void unregisterResumePauseListener(ResumePauseListener *listener)
Q_CORE_EXPORT void unregisterGenericMotionEventListener(GenericMotionEventListener *listener)
Q_CORE_EXPORT bool acquireAndroidDeadlockProtector()
Q_CORE_EXPORT void unregisterKeyEventListener(KeyEventListener *listener)
Q_CORE_EXPORT void handleResume()
Q_CORE_EXPORT void registerResumePauseListener(ResumePauseListener *listener)
Q_CORE_EXPORT void releaseAndroidDeadlockProtector()
Q_CORE_EXPORT void handleNewIntent(JNIEnv *env, jobject intent)
Q_CORE_EXPORT void setOnBindListener(OnBindListener *listener)
Q_CORE_EXPORT void registerKeyEventListener(KeyEventListener *listener)
Q_CORE_EXPORT void handlePause()
Q_CORE_EXPORT bool isUncompressedNativeLibs()
Q_CORE_EXPORT void unregisterActivityResultListener(ActivityResultListener *listener)
Q_CORE_EXPORT void registerGenericMotionEventListener(GenericMotionEventListener *listener)
Q_CORE_EXPORT void handleActivityResult(jint requestCode, jint resultCode, jobject data)
Q_CORE_EXPORT void waitForServiceSetup()
Q_CORE_EXPORT void registerActivityResultListener(ActivityResultListener *listener)
Q_GLOBAL_STATIC(DefaultRoleNames, qDefaultRoleNames, { { Qt::DisplayRole, "display" }, { Qt::DecorationRole, "decoration" }, { Qt::EditRole, "edit" }, { Qt::ToolTipRole, "toolTip" }, { Qt::StatusTipRole, "statusTip" }, { Qt::WhatsThisRole, "whatsThis" }, }) const QHash< int
Q_DECLARE_JNI_NATIVE_METHOD(dispatchKeyEvent)
Q_DECLARE_JNI_NATIVE_METHOD(dispatchGenericMotionEvent)
static jobject g_jClassLoader
static jboolean dispatchGenericMotionEvent(JNIEnv *, jclass, QtJniTypes::MotionEvent event)
Q_GLOBAL_STATIC(QReadWriteLock, g_updateMutex)
static jobject g_jActivity
Q_DECLARE_JNI_CLASS(MotionEvent, "android/view/MotionEvent")
static jboolean updateNativeActivity(JNIEnv *env, jclass=nullptr)
static jboolean dispatchKeyEvent(JNIEnv *, jclass, QtJniTypes::KeyEvent event)
static jobject g_jService