8#include <QtCore/qsharedpointer.h>
10#if defined(Q_QDOC) || defined(Q_OS_ANDROID)
12#include <QtCore/qjnienvironment.h>
13#include <QtCore/qxptype_traits.h>
17class QJniObjectPrivate;
25template <
typename T,
typename =
void>
struct StoresGlobalRefTest : std::false_type {};
27struct StoresGlobalRefTest<T, std::void_t<
decltype(std::declval<T>().object())>>
28 : std::is_same<
decltype(std::declval<T>().object()), jobject>
32template <
typename R,
typename =
void>
33struct CallerHandlesException : std::false_type {
37struct CallerHandlesException<R, std::void_t<
typename R::unexpected_type,
38 typename R::value_type,
39 typename R::error_type>> : std::true_type
41 using value_type =
typename R::value_type;
44template <
typename ReturnType>
45constexpr bool callerHandlesException = CallerHandlesException<ReturnType>::value;
47template <
typename ...Args>
51 bool hasFrame =
false;
53 explicit LocalFrame(JNIEnv *env =
nullptr)
noexcept
60 env->PopLocalFrame(
nullptr);
65 hasFrame = jniEnv()->PushLocalFrame(
sizeof...(Args)) == 0;
68 JNIEnv *jniEnv()
const
71 env = QJniEnvironment::getJniEnv();
76 auto convertToJni(T &&value)
78 using Type = q20::remove_cvref_t<T>;
79 using ResultType =
decltype(QtJniTypes::Traits<Type>::convertToJni(jniEnv(),
80 std::declval<T&&>()));
81 if constexpr (std::is_base_of_v<std::remove_pointer_t<jobject>,
82 std::remove_pointer_t<ResultType>>) {
85 if constexpr (!qxp::is_detected_v<StoresGlobalRefTest, Type>) {
90 return QtJniTypes::Traits<Type>::convertToJni(jniEnv(), std::forward<T>(value));
93 auto convertFromJni(QJniObject &&object)
95 using Type = q20::remove_cvref_t<T>;
96 return QtJniTypes::Traits<Type>::convertFromJni(std::move(object));
100template <
typename Ret,
typename ...Args>
101struct LocalFrameWithReturn : LocalFrame<Args...>
103 using ReturnType = Ret;
105 using LocalFrame<Args...>::LocalFrame;
107 template <
typename T>
108 auto convertFromJni(QJniObject &&object)
110 return LocalFrame<Args...>::
template convertFromJni<T>(std::move(object));
113 template <
typename T>
114 auto convertFromJni(jobject object);
116 bool checkAndClearExceptions()
const
118 if constexpr (callerHandlesException<ReturnType>)
121 return QJniEnvironment::checkAndClearExceptions(
this->jniEnv());
126 if constexpr (callerHandlesException<ReturnType>) {
127 JNIEnv *env =
this->jniEnv();
128 if (env->ExceptionCheck()) {
129 jthrowable exception = env->ExceptionOccurred();
130 env->ExceptionClear();
131 return ReturnType(
typename ReturnType::unexpected_type(exception));
135 checkAndClearExceptions();
139 template <
typename Value>
140 auto makeResult(Value &&value)
142 if constexpr (callerHandlesException<ReturnType>) {
143 auto maybeValue = makeResult();
145 return ReturnType(std::forward<Value>(value));
146 return std::move(maybeValue);
148 checkAndClearExceptions();
149 return std::forward<Value>(value);
156class Q_CORE_EXPORT QJniObject
158 template <
typename Ret,
typename ...Args>
using LocalFrame
159 = QtJniTypes::Detail::LocalFrameWithReturn<Ret, Args...>;
163 explicit QJniObject(
const char *className);
164 explicit QJniObject(
const char *className,
const char *signature, ...);
165 template<
typename ...Args
167 , std::enable_if_t<!std::disjunction_v<QtJniTypes::IsStringType<std::decay_t<Args>>...>>* =
nullptr
170 explicit QJniObject(
const char *className, Args &&...args)
171 : QJniObject(QtJniTypes::Detail::LocalFrame<Args...>{}, className, std::forward<Args>(args)...)
175 template<
typename ...Args>
176 explicit QJniObject(QtJniTypes::Detail::LocalFrame<Args...> localFrame,
const char *className, Args &&...args)
177 : QJniObject(className, QtJniTypes::constructorSignature<Args...>().data(),
178 localFrame.convertToJni(std::forward<Args>(args))...)
182 explicit QJniObject(jclass clazz);
183 explicit QJniObject(jclass clazz,
const char *signature, ...);
184 template<
typename ...Args
186 , std::enable_if_t<!std::disjunction_v<QtJniTypes::IsStringType<std::decay_t<Args>>...>>* =
nullptr
189 explicit QJniObject(jclass clazz, Args &&...args)
190 : QJniObject(clazz, QtJniTypes::constructorSignature<Args...>().data(),
191 std::forward<Args>(args)...)
193 QJniObject(jobject globalRef);
195 QJniObject(
const QJniObject &other)
noexcept =
default;
196 QJniObject(QJniObject &&other)
noexcept =
default;
197 QJniObject &operator=(
const QJniObject &other)
noexcept =
default;
198 QJniObject &operator=(QJniObject &&other)
noexcept =
default;
202 void swap(QJniObject &other)
noexcept { d.swap(other.d); }
204 template<
typename Class,
typename ...Args
206 , QtJniTypes::IfValidSignatureTypes<Class, Args...> =
true
209 static inline auto construct(Args &&...args)
211 LocalFrame<Class, Args...> frame;
212 jclass clazz = QJniObject::loadClassKeepExceptions(QtJniTypes::Traits<Class>::className().data(),
215 ? QJniObject(clazz, QtJniTypes::constructorSignature<Args...>().data(),
216 frame.convertToJni(std::forward<Args>(args))...)
217 : QtJniTypes::Detail::callerHandlesException<Class>
218 ? QJniObject(Qt::Initialization::Uninitialized)
220 return frame.makeResult(std::move(res));
223 jobject object()
const;
224 template <
typename T> T object()
const
226 QtJniTypes::assertObjectType<T>();
227 return static_cast<T>(javaObject());
230 jclass objectClass()
const;
231 QByteArray className()
const;
233 template <
typename ReturnType =
void,
typename ...Args
235 , QtJniTypes::IfValidFieldType<ReturnType> =
true
238 auto callMethod(
const char *methodName,
const char *signature, Args &&...args)
const
240 using Ret =
typename QtJniTypes::Detail::CallerHandlesException<ReturnType>::value_type;
241 LocalFrame<ReturnType, Args...> frame(jniEnv());
242 jmethodID id = getCachedMethodID(frame.jniEnv(), methodName, signature);
244 if constexpr (QtJniTypes::isObjectType<Ret>()) {
245 return frame.makeResult(frame.
template convertFromJni<Ret>(callObjectMethodImpl(
246 id, frame.convertToJni(std::forward<Args>(args))...))
250 if constexpr (std::is_same_v<Ret,
void>) {
251 callVoidMethodV(frame.jniEnv(), id,
252 frame.convertToJni(std::forward<Args>(args))...);
255 callMethodForType<Ret>(frame.jniEnv(), res, object(), id,
256 frame.convertToJni(std::forward<Args>(args))...);
257 return frame.makeResult(res);
260 if constexpr (!std::is_same_v<Ret,
void>)
261 return frame.makeResult(Ret{});
263 return frame.makeResult();
267 template <
typename ReturnType =
void,
typename ...Args
269 , QtJniTypes::IfValidSignatureTypes<ReturnType, Args...> =
true
272 auto callMethod(
const char *methodName, Args &&...args)
const
274 constexpr auto signature = QtJniTypes::methodSignature<ReturnType, Args...>();
275 return callMethod<ReturnType>(methodName, signature.data(), std::forward<Args>(args)...);
278 template <
typename Ret,
typename ...Args
280 , QtJniTypes::IfValidSignatureTypes<Ret, Args...> =
true
283 QJniObject callObjectMethod(
const char *methodName, Args &&...args)
const
285 QtJniTypes::assertObjectType<Ret>();
286 constexpr auto signature = QtJniTypes::methodSignature<Ret, Args...>();
287 LocalFrame<Ret, Args...> frame(jniEnv());
288 auto object = frame.
template convertFromJni<Ret>(callObjectMethod(methodName, signature,
289 frame.convertToJni(std::forward<Args>(args))...));
290 frame.checkAndClearExceptions();
294 QJniObject callObjectMethod(
const char *methodName,
const char *signature, ...)
const;
296 template <
typename Ret =
void,
typename ...Args>
297 static auto callStaticMethod(
const char *className,
const char *methodName,
const char *signature, Args &&...args)
299 LocalFrame<Ret, Args...> frame;
300 jclass clazz = QJniObject::loadClass(className, frame.jniEnv());
301 return callStaticMethod<Ret>(clazz, methodName, signature, std::forward<Args>(args)...);
304 template <
typename Ret =
void,
typename ...Args>
305 static auto callStaticMethod(jclass clazz,
const char *methodName,
const char *signature, Args &&...args)
307 LocalFrame<Ret, Args...> frame;
308 jmethodID id = clazz ? getMethodID(frame.jniEnv(), clazz, methodName, signature,
true)
310 return callStaticMethod<Ret>(clazz, id, std::forward<Args>(args)...);
313 template <
typename ReturnType =
void,
typename ...Args
315 , QtJniTypes::IfValidFieldType<ReturnType> =
true
318 static auto callStaticMethod(jclass clazz, jmethodID methodId, Args &&...args)
320 using Ret =
typename QtJniTypes::Detail::CallerHandlesException<ReturnType>::value_type;
321 LocalFrame<ReturnType, Args...> frame;
322 if constexpr (QtJniTypes::isObjectType<Ret>()) {
323 return frame.makeResult(frame.
template convertFromJni<Ret>(callStaticObjectMethod(
325 frame.convertToJni(std::forward<Args>(args))...))
328 if (clazz && methodId) {
329 if constexpr (std::is_same_v<Ret,
void>) {
330 callStaticMethodForVoid(frame.jniEnv(), clazz, methodId,
331 frame.convertToJni(std::forward<Args>(args))...);
334 callStaticMethodForType<Ret>(frame.jniEnv(), res, clazz, methodId,
335 frame.convertToJni(std::forward<Args>(args))...);
336 return frame.makeResult(res);
339 if constexpr (!std::is_same_v<Ret,
void>)
340 return frame.makeResult(Ret{});
342 return frame.makeResult();
346 template <
typename ReturnType =
void,
typename ...Args
348 , QtJniTypes::IfValidSignatureTypes<ReturnType, Args...> =
true
351 static auto callStaticMethod(
const char *className,
const char *methodName, Args &&...args)
353 using Ret =
typename QtJniTypes::Detail::CallerHandlesException<ReturnType>::value_type;
354 LocalFrame<Ret, Args...> frame;
355 jclass clazz = QJniObject::loadClass(className, frame.jniEnv());
356 const jmethodID id = clazz ? getMethodID(frame.jniEnv(), clazz, methodName,
357 QtJniTypes::methodSignature<Ret, Args...>().data(),
true)
359 return callStaticMethod<ReturnType>(clazz, id, std::forward<Args>(args)...);
362 template <
typename ReturnType =
void,
typename ...Args
364 , QtJniTypes::IfValidSignatureTypes<ReturnType, Args...> =
true
367 static auto callStaticMethod(jclass clazz,
const char *methodName, Args &&...args)
369 constexpr auto signature = QtJniTypes::methodSignature<ReturnType, Args...>();
370 return callStaticMethod<ReturnType>(clazz, methodName, signature.data(), std::forward<Args>(args)...);
372 template <
typename Klass,
typename ReturnType =
void,
typename ...Args
374 , QtJniTypes::IfValidSignatureTypes<ReturnType, Args...> =
true
377 static auto callStaticMethod(
const char *methodName, Args &&...args)
379 LocalFrame<ReturnType, Args...> frame;
380 const jclass clazz = QJniObject::loadClass(QtJniTypes::Traits<Klass>::className().data(),
382 const jmethodID id = clazz ? getMethodID(frame.jniEnv(), clazz, methodName,
383 QtJniTypes::methodSignature<ReturnType, Args...>().data(),
true)
385 return callStaticMethod<ReturnType>(clazz, id, std::forward<Args>(args)...);
388 static QJniObject callStaticObjectMethod(
const char *className,
const char *methodName,
389 const char *signature, ...);
391 static QJniObject callStaticObjectMethod(jclass clazz,
const char *methodName,
392 const char *signature, ...);
394 static QJniObject callStaticObjectMethod(jclass clazz, jmethodID methodId, ...);
397 template <
typename Ret,
typename ...Args
399 , QtJniTypes::IfValidSignatureTypes<Ret, Args...> =
true
402 static QJniObject callStaticObjectMethod(
const char *className,
const char *methodName, Args &&...args)
404 QtJniTypes::assertObjectType<Ret>();
405 constexpr auto signature = QtJniTypes::methodSignature<Ret, Args...>();
406 LocalFrame<QJniObject, Args...> frame;
407 return frame.
template convertFromJni<Ret>(callStaticObjectMethod(className, methodName, signature.data(),
408 frame.convertToJni(std::forward<Args>(args))...));
411 template <
typename Ret,
typename ...Args
413 , QtJniTypes::IfValidSignatureTypes<Ret, Args...> =
true
416 static QJniObject callStaticObjectMethod(jclass clazz,
const char *methodName, Args &&...args)
418 QtJniTypes::assertObjectType<Ret>();
419 constexpr auto signature = QtJniTypes::methodSignature<Ret, Args...>();
420 LocalFrame<QJniObject, Args...> frame;
421 return frame.
template convertFromJni<Ret>(callStaticObjectMethod(clazz, methodName, signature.data(),
422 frame.convertToJni(std::forward<Args>(args))...));
425 template <
typename Type
427 , QtJniTypes::IfValidFieldType<Type> =
true
430 auto getField(
const char *fieldName)
const
432 using T =
typename QtJniTypes::Detail::CallerHandlesException<Type>::value_type;
433 LocalFrame<Type, T> frame(jniEnv());
434 constexpr auto signature = QtJniTypes::fieldSignature<T>();
435 jfieldID id = getCachedFieldID(frame.jniEnv(), fieldName, signature);
437 if constexpr (QtJniTypes::isObjectType<T>()) {
438 return frame.makeResult(frame.
template convertFromJni<T>(getObjectFieldImpl(
444 getFieldForType<T>(frame.jniEnv(), res, object(), id);
445 return frame.makeResult(res);
449 template <
typename Klass,
typename T
451 , QtJniTypes::IfValidFieldType<T> =
true
454 static auto getStaticField(
const char *fieldName)
456 return getStaticField<T>(QtJniTypes::Traits<Klass>::className(), fieldName);
461 , std::enable_if_t<QtJniTypes::isObjectType<T>(),
bool> =
true
464 QJniObject getObjectField(
const char *fieldName)
const
466 constexpr auto signature = QtJniTypes::fieldSignature<T>();
467 return getObjectField(fieldName, signature);
470 QJniObject getObjectField(
const char *fieldName,
const char *signature)
const;
472 template <
typename Type
474 , QtJniTypes::IfValidFieldType<Type> =
true
477 static auto getStaticField(
const char *className,
const char *fieldName)
479 using T =
typename QtJniTypes::Detail::CallerHandlesException<Type>::value_type;
480 LocalFrame<Type, T> frame;
481 jclass clazz = QJniObject::loadClass(className, frame.jniEnv());
482 return getStaticField<Type>(clazz, fieldName);
485 template <
typename Type
487 , QtJniTypes::IfValidFieldType<Type> =
true
490 static auto getStaticField(jclass clazz,
const char *fieldName)
492 using T =
typename QtJniTypes::Detail::CallerHandlesException<Type>::value_type;
493 LocalFrame<Type, T> frame;
494 constexpr auto signature = QtJniTypes::fieldSignature<T>();
495 jfieldID id = clazz ? getFieldID(frame.jniEnv(), clazz, fieldName, signature,
true)
497 if constexpr (QtJniTypes::isObjectType<T>()) {
498 return frame.makeResult(frame.
template convertFromJni<T>(getStaticObjectFieldImpl(
499 frame.jniEnv(), clazz, id))
504 getStaticFieldForType<T>(frame.jniEnv(), res, clazz, id);
505 return frame.makeResult(res);
511 , std::enable_if_t<QtJniTypes::isObjectType<T>(),
bool> =
true
514 static QJniObject getStaticObjectField(
const char *className,
const char *fieldName)
516 constexpr auto signature = QtJniTypes::fieldSignature<T>();
517 return getStaticObjectField(className, fieldName, signature);
520 static QJniObject getStaticObjectField(
const char *className,
521 const char *fieldName,
522 const char *signature);
526 , std::enable_if_t<QtJniTypes::isObjectType<T>(),
bool> =
true
529 static QJniObject getStaticObjectField(jclass clazz,
const char *fieldName)
531 constexpr auto signature = QtJniTypes::fieldSignature<T>();
532 return getStaticObjectField(clazz, fieldName, signature);
535 static QJniObject getStaticObjectField(jclass clazz,
const char *fieldName,
536 const char *signature);
538 template <
typename Ret =
void,
typename Type
540 , QtJniTypes::IfValidFieldType<Type> =
true
543 auto setField(
const char *fieldName, Type value)
546 using T = std::conditional_t<std::is_void_v<Ret> || QtJniTypes::Detail::callerHandlesException<Ret>,
548 LocalFrame<Ret, T> frame(jniEnv());
549 constexpr auto signature = QtJniTypes::fieldSignature<T>();
550 jfieldID id = getCachedFieldID(jniEnv(), fieldName, signature);
552 setFieldForType<T>(jniEnv(), object(), id, value);
553 return frame.makeResult();
556 template <
typename Ret =
void,
typename Type
558 , QtJniTypes::IfValidFieldType<Type> =
true
561 auto setField(
const char *fieldName,
const char *signature, Type value)
564 using T = std::conditional_t<std::is_void_v<Ret> || QtJniTypes::Detail::callerHandlesException<Ret>,
566 LocalFrame<Ret, T> frame(jniEnv());
567 jfieldID id = getCachedFieldID(frame.jniEnv(), fieldName, signature);
569 setFieldForType<T>(jniEnv(), object(), id, value);
570 return frame.makeResult();
573 template <
typename Ret =
void,
typename Type
575 , QtJniTypes::IfValidFieldType<Type> =
true
578 static auto setStaticField(
const char *className,
const char *fieldName, Type value)
581 using T = std::conditional_t<std::is_void_v<Ret> || QtJniTypes::Detail::callerHandlesException<Ret>,
583 LocalFrame<Ret, T> frame;
584 if (jclass clazz = QJniObject::loadClass(className, frame.jniEnv())) {
585 constexpr auto signature = QtJniTypes::fieldSignature<q20::remove_cvref_t<T>>();
586 jfieldID id = getCachedFieldID(frame.jniEnv(), clazz, className, fieldName,
589 setStaticFieldForType<T>(frame.jniEnv(), clazz, id, value);
591 return frame.makeResult();
594 template <
typename Ret =
void,
typename Type
596 , QtJniTypes::IfValidFieldType<Type> =
true
599 static auto setStaticField(
const char *className,
const char *fieldName,
600 const char *signature, Type value)
603 using T = std::conditional_t<std::is_void_v<Ret> || QtJniTypes::Detail::callerHandlesException<Ret>,
605 LocalFrame<Ret, T> frame;
606 if (jclass clazz = QJniObject::loadClass(className, frame.jniEnv())) {
607 jfieldID id = getCachedFieldID(frame.jniEnv(), clazz, className, fieldName,
610 setStaticFieldForType<T>(frame.jniEnv(), clazz, id, value);
612 return frame.makeResult();
615 template <
typename Ret =
void,
typename Type
617 , QtJniTypes::IfValidFieldType<Type> =
true
620 static auto setStaticField(jclass clazz,
const char *fieldName,
621 const char *signature, Type value)
624 using T = std::conditional_t<std::is_void_v<Ret> || QtJniTypes::Detail::callerHandlesException<Ret>,
626 LocalFrame<Ret, T> frame;
627 jfieldID id = getFieldID(frame.jniEnv(), clazz, fieldName, signature,
true);
630 setStaticFieldForType<T>(frame.jniEnv(), clazz, id, value);
631 return frame.makeResult();
634 template <
typename Ret =
void,
typename Type
636 , QtJniTypes::IfValidFieldType<Type> =
true
639 static auto setStaticField(jclass clazz,
const char *fieldName, Type value)
641 return setStaticField<Ret, Type>(clazz, fieldName,
642 QtJniTypes::fieldSignature<q20::remove_cvref_t<Type>>(),
646 template <
typename Klass,
typename Ret =
void,
typename Type
648 , QtJniTypes::IfValidFieldType<Type> =
true
651 static auto setStaticField(
const char *fieldName, Type value)
653 return setStaticField<Ret, Type>(QtJniTypes::Traits<Klass>::className(), fieldName, value);
656 static QJniObject fromString(
const QString &string);
657 QString toString()
const;
659 static bool isClassAvailable(
const char *className);
660 bool isValid()
const;
663 static QJniObject fromLocalRef(jobject lref);
665 template <
typename T,
666 std::enable_if_t<std::is_convertible_v<T, jobject>,
bool> =
true>
667 QJniObject &operator=(T obj)
669 assign(
static_cast<T>(obj));
674 QJniObject(Qt::Initialization) {}
675 JNIEnv *jniEnv()
const noexcept;
678 static jclass loadClass(
const QByteArray &className, JNIEnv *env);
679 static jclass loadClassKeepExceptions(
const QByteArray &className, JNIEnv *env);
681#if QT_CORE_REMOVED_SINCE(6
, 7
)
683 static jclass loadClass(
const QByteArray &className, JNIEnv *env,
bool binEncoded);
684 static QByteArray toBinaryEncClassName(
const QByteArray &className);
685 void callVoidMethodV(JNIEnv *env, jmethodID id, va_list args)
const;
688 static jfieldID getCachedFieldID(JNIEnv *env, jclass clazz,
const QByteArray &className,
689 const char *name,
const char *signature,
690 bool isStatic =
false);
691 jfieldID getCachedFieldID(JNIEnv *env,
const char *name,
const char *signature,
692 bool isStatic =
false)
const;
693 static jmethodID getCachedMethodID(JNIEnv *env, jclass clazz,
const QByteArray &className,
694 const char *name,
const char *signature,
695 bool isStatic =
false);
696 jmethodID getCachedMethodID(JNIEnv *env,
const char *name,
const char *signature,
697 bool isStatic =
false)
const;
699 static jfieldID getFieldID(JNIEnv *env, jclass clazz,
const char *name,
700 const char *signature,
bool isStatic =
false);
701 static jmethodID getMethodID(JNIEnv *env, jclass clazz,
const char *name,
702 const char *signature,
bool isStatic =
false);
704 void callVoidMethodV(JNIEnv *env, jmethodID id, ...)
const;
706 bool isSameObject(jobject obj)
const;
707 bool isSameObject(
const QJniObject &other)
const;
708 void assign(jobject obj);
709 jobject javaObject()
const;
711 friend bool operator==(
const QJniObject &,
const QJniObject &);
712 friend bool operator!=(
const QJniObject&,
const QJniObject&);
715 static constexpr void callMethodForType(JNIEnv *env, T &res, jobject obj, jmethodID id, ...)
722 QtJniTypes::Caller<T>::callMethodForType(env, res, obj, id, args);
726 jobject callObjectMethodImpl(jmethodID method, ...)
const
729 va_start(args, method);
730 jobject res = method ? jniEnv()->CallObjectMethodV(javaObject(), method, args)
737 static constexpr void callStaticMethodForType(JNIEnv *env, T &res, jclass clazz,
744 QtJniTypes::Caller<T>::callStaticMethodForType(env, res, clazz, id, args);
748 static void callStaticMethodForVoid(JNIEnv *env, jclass clazz, jmethodID id, ...)
754 env->CallStaticVoidMethodV(clazz, id, args);
760 static constexpr void getFieldForType(JNIEnv *env, T &res, jobject obj, jfieldID id)
765 QtJniTypes::Caller<T>::getFieldForType(env, res, obj, id);
769 static constexpr void getStaticFieldForType(JNIEnv *env, T &res, jclass clazz, jfieldID id)
771 QtJniTypes::Caller<T>::getStaticFieldForType(env, res, clazz, id);
774 template<
typename Type>
775 static constexpr void setFieldForType(JNIEnv *env, jobject obj, jfieldID id, Type value)
780 using T = q20::remove_cvref_t<Type>;
781 if constexpr (QtJniTypes::isObjectType<T>()) {
782 LocalFrame<T, T> frame(env);
783 env->SetObjectField(obj, id,
static_cast<jobject>(frame.convertToJni(value)));
785 using ValueType =
typename QtJniTypes::Detail::CallerHandlesException<T>::value_type;
786 QtJniTypes::Caller<ValueType>::setFieldForType(env, obj, id, value);
790 jobject getObjectFieldImpl(JNIEnv *env, jfieldID field)
const
792 return field ? env->GetObjectField(javaObject(), field) :
nullptr;
795 static jobject getStaticObjectFieldImpl(JNIEnv *env, jclass clazz, jfieldID field)
797 return clazz && field ? env->GetStaticObjectField(clazz, field)
801 template<
typename Type>
802 static constexpr void setStaticFieldForType(JNIEnv *env, jclass clazz, jfieldID id, Type value)
807 using T = q20::remove_cvref_t<Type>;
808 if constexpr (QtJniTypes::isObjectType<T>()) {
809 LocalFrame<T, T> frame(env);
810 env->SetStaticObjectField(clazz, id,
static_cast<jobject>(frame.convertToJni(value)));
812 QtJniTypes::Caller<T>::setStaticFieldForType(env, clazz, id, value);
816 friend QJniObjectPrivate;
817 QSharedPointer<QJniObjectPrivate> d;
820inline bool operator==(
const QJniObject &obj1,
const QJniObject &obj2)
822 return obj1.isSameObject(obj2);
825inline bool operator!=(
const QJniObject &obj1,
const QJniObject &obj2)
827 return !obj1.isSameObject(obj2);
830namespace QtJniTypes {
833 operator QJniObject()
const {
return m_object; }
835 bool isValid()
const {
return m_object.isValid(); }
836 jclass objectClass()
const {
return m_object.objectClass(); }
837 QString toString()
const {
return m_object.toString(); }
839 template <
typename T = jobject>
841 return m_object.object<T>();
845 JObjectBase() =
default;
846 JObjectBase(
const JObjectBase &) =
default;
847 JObjectBase(JObjectBase &&) =
default;
848 JObjectBase &operator=(
const JObjectBase &) =
default;
849 JObjectBase &operator=(JObjectBase &&) =
default;
850 ~JObjectBase() =
default;
852 Q_IMPLICIT JObjectBase(jobject object) : m_object(object) {}
853 Q_IMPLICIT JObjectBase(
const QJniObject &object) : m_object(object) {}
854 Q_IMPLICIT JObjectBase(QJniObject &&object)
noexcept : m_object(std::move(object)) {}
859template<
typename Type>
860class JObject :
public JObjectBase
866 : JObjectBase{QJniObject(QtJniTypes::Traits<Class>::className())}
868 Q_IMPLICIT JObject(jobject object) : JObjectBase(object) {}
869 Q_IMPLICIT JObject(
const QJniObject &object) : JObjectBase(object) {}
870 Q_IMPLICIT JObject(QJniObject &&object)
noexcept : JObjectBase(std::move(object)) {}
873 JObject(
const JObject &other) =
default;
874 JObject(JObject &&other)
noexcept =
default;
875 JObject &operator=(
const JObject &other) =
default;
876 JObject &operator=(JObject &&other)
noexcept =
default;
878 ~JObject() =
default;
880 template<
typename Arg,
typename ...Args
881 , std::enable_if_t<!std::is_same_v<q20::remove_cvref_t<Arg>, JObject>,
bool> =
true
882 , IfValidSignatureTypes<Arg, Args...> =
true
884 explicit JObject(Arg && arg, Args &&...args)
885 : JObjectBase{QJniObject(QtJniTypes::Traits<Class>::className(),
886 std::forward<Arg>(arg), std::forward<Args>(args)...)}
890 static JObject fromJObject(jobject object)
892 return JObject(object);
894 template <
typename ...Args>
895 static JObject construct(Args &&...args)
897 return JObject(std::forward<Args>(args)...);
899 static JObject fromLocalRef(jobject lref)
901 return JObject(QJniObject::fromLocalRef(lref));
905 bool isValid()
const;
906 jclass objectClass()
const;
907 QString toString()
const;
908 template <
typename T = jobject> object()
const;
911 static bool registerNativeMethods(std::initializer_list<JNINativeMethod> methods)
914 return env.registerNativeMethods<Class>(methods);
918 template <
typename Ret =
void,
typename ...Args
920 , QtJniTypes::IfValidSignatureTypes<Ret, Args...> =
true
923 static auto callStaticMethod(
const char *name, Args &&...args)
925 return QJniObject::callStaticMethod<Class, Ret, Args...>(name,
926 std::forward<Args>(args)...);
930 , QtJniTypes::IfValidFieldType<T> =
true
933 static auto getStaticField(
const char *field)
935 return QJniObject::getStaticField<Class, T>(field);
937 template <
typename Ret =
void,
typename T
939 , QtJniTypes::IfValidFieldType<T> =
true
942 static auto setStaticField(
const char *field, T &&value)
944 return QJniObject::setStaticField<Class, Ret, T>(field, std::forward<T>(value));
948 template <
typename Ret =
void,
typename ...Args
950 , QtJniTypes::IfValidSignatureTypes<Ret, Args...> =
true
953 auto callMethod(
const char *method, Args &&...args)
const
955 return m_object.callMethod<Ret>(method, std::forward<Args>(args)...);
959 , QtJniTypes::IfValidFieldType<T> =
true
962 auto getField(
const char *fieldName)
const
964 return m_object.getField<T>(fieldName);
967 template <
typename Ret =
void,
typename T
969 , QtJniTypes::IfValidFieldType<T> =
true
972 auto setField(
const char *fieldName, T &&value)
974 return m_object.setField<Ret>(fieldName, std::forward<T>(value));
977 QByteArray className()
const {
978 return QtJniTypes::Traits<Class>::className().data();
981 static bool isClassAvailable()
983 return QJniObject::isClassAvailable(QtJniTypes::Traits<Class>::className().data());
987 friend bool comparesEqual(
const JObject &lhs,
const JObject &rhs)
988 {
return lhs.m_object == rhs.m_object; }
989 Q_DECLARE_EQUALITY_COMPARABLE_NON_NOEXCEPT(JObject);
992template <
typename T>
struct Traits<JObject<T>> {
993 static constexpr auto signature() {
return Traits<T>::signature(); }
994 static constexpr auto className() {
return Traits<T>::className(); }
995 static auto convertToJni(JNIEnv *,
const JObject<T> &value)
997 return value.object();
999 static auto convertFromJni(QJniObject &&object)
1001 return JObject<T>(std::move(object));
1006struct Traits<QJniObject>
1008 static constexpr auto className()
1010 return CTString(
"java/lang/Object");
1013 static constexpr auto signature()
1015 return CTString(
"Ljava/lang/Object;");
1018 static auto convertToJni(JNIEnv *,
const QJniObject &value)
1020 return value.object();
1022 static auto convertFromJni(QJniObject &&object)
1024 return std::move(object);
1029struct Traits<QString>
1031 static constexpr auto className()
1033 return CTString(
"java/lang/String");
1035 static constexpr auto signature()
1037 return CTString(
"Ljava/lang/String;");
1040 static auto convertToJni(JNIEnv *env,
const QString &value)
1042 return QtJniTypes::Detail::fromQString(value, env);
1045 static auto convertFromJni(QJniObject &&object)
1047 return object.toString();
1051template <
typename T>
1052struct Traits<T, std::enable_if_t<QtJniTypes::Detail::callerHandlesException<T>>>
1054 static constexpr auto className()
1056 return Traits<
typename T::value_type>::className();
1059 static constexpr auto signature()
1061 return Traits<
typename T::value_type>::signature();
1067template <
typename ReturnType,
typename ...Args>
1068template <
typename T>
1069auto QtJniTypes::Detail::LocalFrameWithReturn<ReturnType, Args...>::convertFromJni(jobject object)
1077 if constexpr (callerHandlesException<ReturnType> &&
1078 std::is_base_of_v<std::remove_pointer_t<jobject>, std::remove_pointer_t<T>>)
1079 return static_cast<T>(object);
1081 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