summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAssam Boudjelthia <assam.boudjelthia@qt.io>2021-02-01 15:08:21 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-02-09 18:23:26 +0000
commit77b035aa6e73ce317242a21f181a8e5849a36bee (patch)
tree3a851742d6f269624ac8462821b8063cf9ac6da0 /src
parentbbdcc86c52d806ab45fabf167526f9dcec291648 (diff)
Documentation improvements to JNI API
Amends 4e60681c879a54cf5b34862a30e27c492ed36363. Fixes: QTBUG-89632 Change-Id: I7856e9b63eea5ba68a5472575016540ae656ec5f Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io> Reviewed-by: Alex Blasche <alexander.blasche@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> (cherry picked from commit 817f8ac03cd4e85b7813b45f8cabf5b679f28702) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/doc/snippets/jni/src_qjniobject.cpp21
-rw-r--r--src/corelib/doc/src/external-resources.qdoc27
-rw-r--r--src/corelib/kernel/qjnienvironment.cpp68
-rw-r--r--src/corelib/kernel/qjniobject.cpp456
-rw-r--r--src/corelib/kernel/qjniobject.h54
5 files changed, 362 insertions, 264 deletions
diff --git a/src/corelib/doc/snippets/jni/src_qjniobject.cpp b/src/corelib/doc/snippets/jni/src_qjniobject.cpp
index f3433134db..b729987d4f 100644
--- a/src/corelib/doc/snippets/jni/src_qjniobject.cpp
+++ b/src/corelib/doc/snippets/jni/src_qjniobject.cpp
@@ -79,7 +79,7 @@ void functionScope()
}
//! [QJniObject scope]
-//! [Registering native methods]
+//! [C++ native methods]
static void fromJavaOne(JNIEnv *env, jobject thiz, jint x)
{
Q_UNUSED(env);
@@ -94,26 +94,19 @@ static void fromJavaTwo(JNIEnv *env, jobject thiz, jint x)
qDebug() << x << ">= 100";
}
-void registerNativeMethods() {
+void foo()
+{
+ // register the native methods first, ideally it better be done with the app start
JNINativeMethod methods[] {{"callNativeOne", "(I)V", reinterpret_cast<void *>(fromJavaOne)},
{"callNativeTwo", "(I)V", reinterpret_cast<void *>(fromJavaTwo)}};
-
- QJniObject javaClass("my/java/project/FooJavaClass");
QJniEnvironment env;
- jclass objectClass = env->GetObjectClass(javaClass.object<jobject>());
- env->RegisterNatives(objectClass,
- methods,
- sizeof(methods) / sizeof(methods[0]));
- env->DeleteLocalRef(objectClass);
-}
+ env.registerNativeMethods("my/java/project/FooJavaClass", methods, 2);
-void foo()
-{
+ // Call the java method which will calls back to the C++ functions
QJniObject::callStaticMethod<void>("my/java/project/FooJavaClass", "foo", "(I)V", 10); // Output: 10 < 100
QJniObject::callStaticMethod<void>("my/java/project/FooJavaClass", "foo", "(I)V", 100); // Output: 100 >= 100
}
-
-//! [Registering native methods]
+//! [C++ native methods]
//! [Java native methods]
class FooJavaClass
diff --git a/src/corelib/doc/src/external-resources.qdoc b/src/corelib/doc/src/external-resources.qdoc
index c3dc67a705..583e668be4 100644
--- a/src/corelib/doc/src/external-resources.qdoc
+++ b/src/corelib/doc/src/external-resources.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
@@ -65,3 +65,28 @@
\externalpage https://marcmutz.wordpress.com/effective-qt/containers/
\title Understand the Qt Containers
*/
+
+/*!
+ \externalpage https://developer.android.com/training/articles/perf-jni#javavm-and-jnienv
+ \title JNI tips: JavaVM and JNIEnv
+*/
+
+/*!
+ \externalpage https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html
+ \title Java Native Interface Specification
+*/
+
+/*!
+ \externalpage https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html
+ \title Oracle: JNI Functions
+*/
+
+/*!
+ \externalpage https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#global_and_local_references
+ \title JNI Design Overview: Global and Local References
+*/
+
+/*!
+ \externalpage https://developer.android.com/training/articles/perf-jni#local-and-global-references
+ \title JNI tips: Local and global references
+*/
diff --git a/src/corelib/kernel/qjnienvironment.cpp b/src/corelib/kernel/qjnienvironment.cpp
index 4e52f33e0c..eea62116d6 100644
--- a/src/corelib/kernel/qjnienvironment.cpp
+++ b/src/corelib/kernel/qjnienvironment.cpp
@@ -49,11 +49,19 @@ QT_BEGIN_NAMESPACE
/*!
\class QJniEnvironment
\inmodule QtCore
- \brief The QJniEnvironment provides access to the JNI Environment.
\since 6.1
+ \brief The QJniEnvironment class provides access to the JNI Environment (JNIEnv).
- \note This API has been tested and meant to be mainly used for Android and it hasn't been tested
- for other platforms.
+ When using JNI, the \l {JNI tips: JavaVM and JNIEnv}{JNIEnv} class is a pointer to a function
+ table and a member function for each JNI function that indirects through the table. \c JNIEnv
+ provides most of the JNI functions. Every C++ native function receives a \c JNIEnv as the first
+ argument. The JNI environment cannot be shared between threads.
+
+ Since \c JNIEnv doesn't do much error checking, such as exception checking and clearing,
+ QJniEnvironment allows you to do that easily.
+
+ \note This API has been designed and tested for use with Android.
+ It has not been tested for other platforms.
*/
static const char qJniThreadName[] = "QtThread";
@@ -96,7 +104,7 @@ Q_GLOBAL_STATIC(QThreadStorage<QJniEnvironmentPrivateTLS *>, jniEnvTLS)
/*!
\fn QJniEnvironment::QJniEnvironment()
- Constructs a new QJniEnvironment object and attaches the current thread to the Java VM.
+ Constructs a new JNI Environment object and attaches the current thread to the Java VM.
*/
QJniEnvironment::QJniEnvironment()
: d(new QJniEnvironmentPrivate{})
@@ -120,6 +128,7 @@ QJniEnvironment::QJniEnvironment()
\fn QJniEnvironment::~QJniEnvironment()
Detaches the current thread from the Java VM and destroys the QJniEnvironment object.
+ This will clear any pending exception by calling exceptionCheckAndClear().
*/
QJniEnvironment::~QJniEnvironment()
{
@@ -152,13 +161,13 @@ QJniEnvironment::operator JNIEnv* () const
Searches for \a className using all available class loaders. Qt on Android
uses a custom class loader to load all the .jar files and it must be used
to find any classes that are created by that class loader because these
- classes are not visible in the default class loader.
+ classes are not visible when using the default class loader.
Returns the class pointer or null if is not found.
A use case for this function is searching for a custom class then calling
- its memeber method. The following code snippet create an instance of the
- class \c CustomClass and then calls \c printFromJava() method:
+ its member method. The following code snippet creates an instance of the
+ class \c CustomClass and then calls the \c printFromJava() method:
\code
QJniEnvironment env;
@@ -170,8 +179,6 @@ QJniEnvironment::operator JNIEnv* () const
"(Ljava/lang/String;)V",
javaMessage.object<jstring>());
\endcode
-
- \since Qt 6.1
*/
jclass QJniEnvironment::findClass(const char *className)
{
@@ -181,9 +188,9 @@ jclass QJniEnvironment::findClass(const char *className)
/*!
\fn JavaVM *QJniEnvironment::javaVM()
- Returns the Java VM interface.
+ Returns the Java VM interface for the current process. Although it might
+ be possible to have multiple Java VMs per process, Android allows only one.
- \since Qt 6.1
*/
JavaVM *QJniEnvironment::javaVM()
{
@@ -191,10 +198,11 @@ JavaVM *QJniEnvironment::javaVM()
}
/*!
- \fn bool QJniEnvironment::registerNativeMethods(const char *className, JNINativeMethod methods[])
+ \fn bool QJniEnvironment::registerNativeMethods(const char *className, JNINativeMethod methods[], int size)
- Registers the Java methods \a methods that can call native C++ functions from class \a
- className. These methods must be registered before any attempt to call them.
+ Registers the Java methods in the array \a methods of size \a size, each of
+ which can call native C++ functions from class \a className. These methods
+ must be registered before any attempt to call them.
Returns True if the registration is successful, otherwise False.
@@ -209,10 +217,8 @@ JavaVM *QJniEnvironment::javaVM()
JNINativeMethod methods[] {{"callNativeOne", "(I)V", reinterpret_cast<void *>(fromJavaOne)},
{"callNativeTwo", "(I)V", reinterpret_cast<void *>(fromJavaTwo)}};
QJniEnvironment env;
- env.registerNativeMethods("org/qtproject/android/TestJavaClass", methods);
+ env.registerNativeMethods("org/qtproject/android/TestJavaClass", methods, 2);
\endcode
-
- \since Qt 6.1
*/
bool QJniEnvironment::registerNativeMethods(const char *className, JNINativeMethod methods[], int size)
{
@@ -233,18 +239,23 @@ bool QJniEnvironment::registerNativeMethods(const char *className, JNINativeMeth
}
/*!
- \enum QJniExceptionCleaner::OutputMode
+ \enum QJniEnvironment::OutputMode
- \value Silent the exceptions are cleaned silently
- \value Verbose describes the exceptions before cleaning them
+ \value Silent The exceptions are cleaned silently
+ \value Verbose Prints the exceptions and their stack backtrace as an error
+ to \c stderr stream.
*/
/*!
- \fn QJniEnvironment::exceptionCheckAndClear(OutputMode outputMode = OutputMode::Silent)
+ \fn QJniEnvironment::exceptionCheckAndClear(OutputMode outputMode = OutputMode::Verbose)
- Cleans any pending exceptions either silently or with descriptions, depending on the \a outputMode.
+ Cleans any pending exceptions either silently or reporting stack backtrace,
+ depending on the \a outputMode.
- \since 6.1
+ In contrast to \l QJniObject, which handles exceptions internally, if you
+ make JNI calls directly via \c JNIEnv, you need to clear any potential
+ exceptions after the call using this function. For more information about
+ \c JNIEnv calls that can throw an exception, see \l {Oracle: JNI Functions}{JNI Functions}.
*/
bool QJniEnvironment::exceptionCheckAndClear(QJniEnvironment::OutputMode outputMode)
{
@@ -260,11 +271,16 @@ bool QJniEnvironment::exceptionCheckAndClear(QJniEnvironment::OutputMode outputM
}
/*!
- \fn QJniEnvironment::exceptionCheckAndClear(JNIEnv *env, OutputMode outputMode = OutputMode::Silent)
+ \fn QJniEnvironment::exceptionCheckAndClear(JNIEnv *env, OutputMode outputMode = OutputMode::Verbose)
- Cleans any pending exceptions for \a env, either silently or with descriptions, depending on the \a outputMode.
+ Cleans any pending exceptions for \a env, either silently or reporting
+ stack backtrace, depending on the \a outputMode. This is useful when you
+ already have a \c JNIEnv pointer such as in a native function implementation.
- \since 6.1
+ In contrast to \l QJniObject, which handles exceptions internally, if you
+ make JNI calls directly via \c JNIEnv, you need to clear any potential
+ exceptions after the call using this function. For more information about
+ \c JNIEnv calls that can throw an exception, see \l {Oracle: JNI Functions}{JNI Functions}.
*/
bool QJniEnvironment::exceptionCheckAndClear(JNIEnv *env, QJniEnvironment::OutputMode outputMode)
{
diff --git a/src/corelib/kernel/qjniobject.cpp b/src/corelib/kernel/qjniobject.cpp
index ba7d0af778..6059ad4bf7 100644
--- a/src/corelib/kernel/qjniobject.cpp
+++ b/src/corelib/kernel/qjniobject.cpp
@@ -49,22 +49,28 @@ QT_BEGIN_NAMESPACE
/*!
\class QJniObject
\inmodule QtCore
- \brief Provides a convenient set of APIs to call Java code from C++ using the Java Native Interface (JNI).
\since 6.1
+ \brief A convenience wrapper around the Java Native Interface (JNI).
+
+ The QJniObject class wraps a reference to a Java object, ensuring it isn't
+ gargage-collected and providing access to most \c JNIEnv method calls
+ (member, static) and fields (setter, getter). It eliminates much
+ boiler-plate that would normally be needed, with direct JNI access, for
+ every operation, including exception-handling.
+
+ \note This API has been designed and tested for use with Android.
+ It has not been tested for other platforms.
\sa QJniEnvironment
\section1 General Notes
\list
- \li Class names needs to contain the fully-qualified class name, for example: \b"java/lang/String".
- \li Method signatures are written as \b"(Arguments)ReturnType"
+ \li Class names need to be fully-qualified, for example: \c "java/lang/String".
+ \li Method signatures are written as \c "(ArgumentsTypes)ReturnType", see \l {JNI Types}.
\li All object types are returned as a QJniObject.
\endlist
- \note This API has been tested and meant to be mainly used for Android and it hasn't been tested
- for other platforms.
-
\section1 Method Signatures
For functions that take no arguments, QJniObject provides convenience functions that will use
@@ -76,11 +82,12 @@ QT_BEGIN_NAMESPACE
\endcode
In other cases you will need to supply the signature yourself, and it is important that the
- signature matches the function you want to call. The signature structure is \b \(A\)R, where \b A
- is the type of the argument\(s\) and \b R is the return type. Array types in the signature must
- have the \b\[ suffix and the fully-qualified type names must have the \b L prefix and \b ; suffix.
+ signature matches the function you want to call. The signature structure is
+ \c "(ArgumentsTypes)ReturnType". Array types in the signature must have the \c {[} prefix,
+ and the fully-qualified \c Object type names must have the \c L prefix and the \c ; suffix.
+
+ The example below demonstrates how to call two different static functions:
- The example below demonstrates how to call two different static functions.
\code
// Java class
package org.qtproject.qt;
@@ -91,45 +98,48 @@ QT_BEGIN_NAMESPACE
}
\endcode
- The signature for the first function is \b"\(I\)Ljava/lang/String;"
+ The signature for the first function is \c {"\(I\)Ljava/lang/String;"}:
\code
// C++ code
QJniObject stringNumber = QJniObject::callStaticObjectMethod("org/qtproject/qt/TestClass",
- "fromNumber"
- "(I)Ljava/lang/String;",
- 10);
+ "fromNumber"
+ "(I)Ljava/lang/String;",
+ 10);
\endcode
- and the signature for the second function is \b"\(Ljava/lang/String;Ljava/lang/String;\)\[Ljava/lang/String;"
+ and the signature for the second function is
+ \c "\(Ljava/lang/String;Ljava/lang/String;\)\[Ljava/lang/String;":
\code
// C++ code
QJniObject string1 = QJniObject::fromString("String1");
QJniObject string2 = QJniObject::fromString("String2");
QJniObject stringArray = QJniObject::callStaticObjectMethod("org/qtproject/qt/TestClass",
- "stringArray"
- "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;"
- string1.object<jstring>(),
- string2.object<jstring>());
+ "stringArray"
+ "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;"
+ string1.object<jstring>(),
+ string2.object<jstring>());
\endcode
-
\section1 Handling Java Exception
- When calling Java functions that might throw an exception, it is important that you check, handle
- and clear out the exception before continuing.
+ After calling Java functions that might throw exceptions, it is important
+ to check for, handle and clear out any exception before continuing. All
+ QJniObject functions handle exceptions internally by reporting and clearing them,
+ saving client code the need to handle exceptions.
- \note It is unsafe to make a JNI call when there are exceptions pending. For more information,
- see QJniEnvironment::exceptionCheckAndClear().
+ \note The user must handle exceptions manually when doing JNI calls using \c JNIEnv directly.
+ It is unsafe to make other JNI calls when exceptions are pending. For more information, see
+ QJniEnvironment::exceptionCheckAndClear().
\section1 Java Native Methods
Java native methods makes it possible to call native code from Java, this is done by creating a
- function declaration in Java and prefixing it with the \b native keyword.
+ function declaration in Java and prefixing it with the \c native keyword.
Before a native function can be called from Java, you need to map the Java native function to a
- native function in your code. Mapping functions can be done by calling the RegisterNatives() function
- through the \l{QJniEnvironment}{JNI environment pointer}.
+ native function in your code. Mapping functions can be done by calling
+ QJniEnvironment::registerNativeMethods().
The example below demonstrates how this could be done.
@@ -137,14 +147,25 @@ QT_BEGIN_NAMESPACE
\snippet jni/src_qjniobject.cpp Java native methods
C++ Implementation:
- \snippet jni/src_qjniobject.cpp Registering native methods
+ \snippet jni/src_qjniobject.cpp C++ native methods
\section1 The Lifetime of a Java Object
- Most \l{Object types}{objects} received from Java will be local references and will only stay valid
- in the scope you received them. After that, the object becomes eligible for garbage collection. If you
- want to keep a Java object alive you need to either create a new global reference to the object and
- release it when you are done, or construct a new QJniObject and let it manage the lifetime of the Java object.
+ Most \l{Object types}{objects} received from Java will be local references
+ and will only stay valid until you return from the native method. After that,
+ the object becomes eligible for garbage collection. If your code creates
+ many local references in a loop you should delete them manually with each
+ iteration, otherwise you might run out of memory. For more information, see
+ \l {JNI Design Overview: Global and Local References}. Local references
+ created outside a native method scope must be deleted manually, since
+ the garbage collector will not free them automatically because we are using
+ \c AttachCurrentThread. For more information, see
+ \l {JNI tips: Local and global references}.
+
+ If you want to keep a Java object alive you need to either create a new global
+ reference to the object and release it when you are done, or construct a new
+ QJniObject and let it manage the lifetime of the Java object.
+
\sa object()
\note The QJniObject only manages its own references, if you construct a QJniObject from a
@@ -245,7 +266,7 @@ QT_BEGIN_NAMESPACE
\li L\e<fully-qualified-name>;
\endtable
- For more information about JNI see: \l http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html
+ For more information about JNI, see \l {Java Native Interface Specification}.
*/
/*!
@@ -338,11 +359,11 @@ Q_GLOBAL_STATIC(QReadWriteLock, cachedMethodIDLock)
static inline jmethodID getMethodID(JNIEnv *env,
jclass clazz,
const char *name,
- const char *sig,
+ const char *signature,
bool isStatic = false)
{
- jmethodID id = isStatic ? env->GetStaticMethodID(clazz, name, sig)
- : env->GetMethodID(clazz, name, sig);
+ jmethodID id = isStatic ? env->GetStaticMethodID(clazz, name, signature)
+ : env->GetMethodID(clazz, name, signature);
if (QJniEnvironment::exceptionCheckAndClear(env))
return nullptr;
@@ -354,13 +375,15 @@ static jmethodID getCachedMethodID(JNIEnv *env,
jclass clazz,
const QByteArray &className,
const char *name,
- const char *sig,
+ const char *signature,
bool isStatic = false)
{
if (className.isEmpty())
- return getMethodID(env, clazz, name, sig, isStatic);
+ return getMethodID(env, clazz, name, signature, isStatic);
- const QString key = keyBase().arg(QLatin1String(className), QLatin1String(name), QLatin1String(sig));
+ const QString key = keyBase().arg(QLatin1String(className),
+ QLatin1String(name),
+ QLatin1String(signature));
QHash<QString, jmethodID>::const_iterator it;
{
@@ -376,7 +399,7 @@ static jmethodID getCachedMethodID(JNIEnv *env,
if (it != cachedMethodID->constEnd())
return it.value();
- jmethodID id = getMethodID(env, clazz, name, sig, isStatic);
+ jmethodID id = getMethodID(env, clazz, name, signature, isStatic);
cachedMethodID->insert(key, id);
return id;
@@ -390,11 +413,11 @@ Q_GLOBAL_STATIC(QReadWriteLock, cachedFieldIDLock)
static inline jfieldID getFieldID(JNIEnv *env,
jclass clazz,
const char *name,
- const char *sig,
+ const char *signature,
bool isStatic = false)
{
- jfieldID id = isStatic ? env->GetStaticFieldID(clazz, name, sig)
- : env->GetFieldID(clazz, name, sig);
+ jfieldID id = isStatic ? env->GetStaticFieldID(clazz, name, signature)
+ : env->GetFieldID(clazz, name, signature);
if (QJniEnvironment::exceptionCheckAndClear(env))
return nullptr;
@@ -406,13 +429,15 @@ static jfieldID getCachedFieldID(JNIEnv *env,
jclass clazz,
const QByteArray &className,
const char *name,
- const char *sig,
+ const char *signature,
bool isStatic = false)
{
if (className.isNull())
- return getFieldID(env, clazz, name, sig, isStatic);
+ return getFieldID(env, clazz, name, signature, isStatic);
- const QString key = keyBase().arg(QLatin1String(className), QLatin1String(name), QLatin1String(sig));
+ const QString key = keyBase().arg(QLatin1String(className),
+ QLatin1String(name),
+ QLatin1String(signature));
QHash<QString, jfieldID>::const_iterator it;
{
@@ -428,7 +453,7 @@ static jfieldID getCachedFieldID(JNIEnv *env,
if (it != cachedFieldID->constEnd())
return it.value();
- jfieldID id = getFieldID(env, clazz, name, sig, isStatic);
+ jfieldID id = getFieldID(env, clazz, name, signature, isStatic);
cachedFieldID->insert(key, id);
return id;
@@ -491,7 +516,7 @@ public:
/*!
\fn QJniObject::QJniObject()
- Constructs an invalid QJniObject.
+ Constructs an invalid JNI object.
\sa isValid()
*/
@@ -503,7 +528,7 @@ QJniObject::QJniObject()
/*!
\fn QJniObject::QJniObject(const char *className)
- Constructs a new QJniObject by calling the default constructor of \a className.
+ Constructs a new JNI object by calling the default constructor of \a className.
\code
QJniObject myJavaString("java/lang/String");
@@ -532,8 +557,8 @@ QJniObject::QJniObject(const char *className)
/*!
\fn QJniObject::QJniObject(const char *className, const char *signature, ...)
- Constructs a new QJniObject by calling the constructor of \a className with \a signature
- and arguments.
+ Constructs a new JNI object by calling the constructor of \a className with
+ \a signature specifying the types of any subsequent arguments.
\code
QJniEnvironment env;
@@ -542,7 +567,7 @@ QJniObject::QJniObject(const char *className)
QJniObject myNewJavaString("java/lang/String", "(Ljava/lang/String;)V", myJStringArg);
\endcode
*/
-QJniObject::QJniObject(const char *className, const char *sig, ...)
+QJniObject::QJniObject(const char *className, const char *signature, ...)
: d(new QJniObjectPrivate())
{
QJniEnvironment env;
@@ -550,10 +575,10 @@ QJniObject::QJniObject(const char *className, const char *sig, ...)
d->m_jclass = loadClass(d->m_className, env, true);
d->m_own_jclass = false;
if (d->m_jclass) {
- jmethodID constructorId = getCachedMethodID(env, d->m_jclass, d->m_className, "<init>", sig);
+ jmethodID constructorId = getCachedMethodID(env, d->m_jclass, d->m_className, "<init>", signature);
if (constructorId) {
va_list args;
- va_start(args, sig);
+ va_start(args, signature);
jobject obj = env->NewObjectV(d->m_jclass, constructorId, args);
va_end(args);
if (obj) {
@@ -564,7 +589,7 @@ QJniObject::QJniObject(const char *className, const char *sig, ...)
}
}
-QJniObject::QJniObject(const char *className, const char *sig, const QVaListPrivate &args)
+QJniObject::QJniObject(const char *className, const char *signature, const QVaListPrivate &args)
: d(new QJniObjectPrivate())
{
QJniEnvironment env;
@@ -572,7 +597,7 @@ QJniObject::QJniObject(const char *className, const char *sig, const QVaListPriv
d->m_jclass = loadClass(d->m_className, env, true);
d->m_own_jclass = false;
if (d->m_jclass) {
- jmethodID constructorId = getCachedMethodID(env, d->m_jclass, d->m_className, "<init>", sig);
+ jmethodID constructorId = getCachedMethodID(env, d->m_jclass, d->m_className, "<init>", signature);
if (constructorId) {
jobject obj = env->NewObjectV(d->m_jclass, constructorId, args);
if (obj) {
@@ -586,8 +611,8 @@ QJniObject::QJniObject(const char *className, const char *sig, const QVaListPriv
/*!
\fn QJniObject::QJniObject(jclass clazz, const char *signature, ...)
- Constructs a new QJniObject from \a clazz by calling the constructor with \a signature
- and arguments.
+ Constructs a new JNI object from \a clazz by calling the constructor with
+ \a signature specifying the types of any subsequent arguments.
\code
QJniEnvironment env;
@@ -595,17 +620,17 @@ QJniObject::QJniObject(const char *className, const char *sig, const QVaListPriv
QJniObject(myClazz, "(I)V", 3);
\endcode
*/
-QJniObject::QJniObject(jclass clazz, const char *sig, ...)
+QJniObject::QJniObject(jclass clazz, const char *signature, ...)
: d(new QJniObjectPrivate())
{
QJniEnvironment env;
if (clazz) {
d->m_jclass = static_cast<jclass>(env->NewGlobalRef(clazz));
if (d->m_jclass) {
- jmethodID constructorId = getMethodID(env, d->m_jclass, "<init>", sig);
+ jmethodID constructorId = getMethodID(env, d->m_jclass, "<init>", signature);
if (constructorId) {
va_list args;
- va_start(args, sig);
+ va_start(args, signature);
jobject obj = env->NewObjectV(d->m_jclass, constructorId, args);
va_end(args);
if (obj) {
@@ -620,9 +645,9 @@ QJniObject::QJniObject(jclass clazz, const char *sig, ...)
/*!
\fn QJniObject::QJniObject(jclass clazz)
- Constructs a new QJniObject by calling the default constructor of \a clazz.
+ Constructs a new JNI object by calling the default constructor of \a clazz.
- Note: The QJniObject will create a new reference to the class \a clazz
+ \note The QJniObject will create a new reference to the class \a clazz
and releases it again when it is destroyed. References to the class created
outside the QJniObject need to be managed by the caller.
*/
@@ -645,14 +670,14 @@ QJniObject::QJniObject(jclass clazz)
}
}
-QJniObject::QJniObject(jclass clazz, const char *sig, const QVaListPrivate &args)
+QJniObject::QJniObject(jclass clazz, const char *signature, const QVaListPrivate &args)
: d(new QJniObjectPrivate())
{
QJniEnvironment env;
if (clazz) {
d->m_jclass = static_cast<jclass>(env->NewGlobalRef(clazz));
if (d->m_jclass) {
- jmethodID constructorId = getMethodID(env, d->m_jclass, "<init>", sig);
+ jmethodID constructorId = getMethodID(env, d->m_jclass, "<init>", signature);
if (constructorId) {
jobject obj = env->NewObjectV(d->m_jclass, constructorId, args);
if (obj) {
@@ -667,7 +692,7 @@ QJniObject::QJniObject(jclass clazz, const char *sig, const QVaListPrivate &args
/*!
\fn QJniObject::QJniObject(jobject object)
- Constructs a new QJniObject around the Java object \a object.
+ Constructs a new JNI object around the Java object \a object.
\note The QJniObject will hold a reference to the Java object \a object
and release it when destroyed. Any references to the Java object \a object
@@ -694,43 +719,40 @@ QJniObject::QJniObject(jobject obj)
/*!
\fn QJniObject::~QJniObject()
- Destroys the QJniObject and releases any references held by the QJniObject.
+ Destroys the JNI object and releases any references held by the JNI object.
*/
QJniObject::~QJniObject()
{}
/*!
- \fn template <typename T> T QJniObject::object() const
+ \fn jobject QJniObject::object() const
- Returns the object held by the QJniObject as type T.
+ Returns the object held by the QJniObject as jobject.
\code
- QJniObject string = QJniObject::fromString("Hello, JNI");
- jstring jstring = string.object<jstring>();
+ jobject object = jniObject.object();
\endcode
- \note The returned object is still owned by the QJniObject. If you want to keep the object valid
- you should create a new QJniObject or make a new global reference to the object and
- free it yourself.
+ \note The returned object is still kept live by this QJniObject. To keep the
+ object live beyond the lifetime of this QJniObject, for example to record it
+ for later use, the easiest approach is to store it in another QJniObject with
+ a suitable lifetime. Alternatively, you can make a new global reference to the
+ object and store it, taking care to free it when you are done with it.
\snippet jni/src_qjniobject.cpp QJniObject scope
-
- \code
- jobject object = jniObject.object();
- \endcode
*/
-Q_CORE_EXPORT jobject QJniObject::object() const
+jobject QJniObject::object() const
{
return javaObject();
}
QJniObject QJniObject::callObjectMethodV(const char *methodName,
- const char *sig,
+ const char *signature,
va_list args) const
{
QJniEnvironment env;
jobject res = nullptr;
- jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig);
+ jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, signature);
if (id) {
res = env->CallObjectMethodV(d->m_jobject, id, args);
if (env.exceptionCheckAndClear()) {
@@ -746,14 +768,15 @@ QJniObject QJniObject::callObjectMethodV(const char *methodName,
QJniObject QJniObject::callStaticObjectMethodV(const char *className,
const char *methodName,
- const char *sig,
+ const char *signature,
va_list args)
{
QJniEnvironment env;
jobject res = nullptr;
jclass clazz = loadClass(className, env);
if (clazz) {
- jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true);
+ jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className),
+ methodName, signature, true);
if (id) {
res = env->CallStaticObjectMethodV(clazz, id, args);
if (env.exceptionCheckAndClear()) {
@@ -770,12 +793,12 @@ QJniObject QJniObject::callStaticObjectMethodV(const char *className,
QJniObject QJniObject::callStaticObjectMethodV(jclass clazz,
const char *methodName,
- const char *sig,
+ const char *signature,
va_list args)
{
QJniEnvironment env;
jobject res = nullptr;
- jmethodID id = getMethodID(env, clazz, methodName, sig, true);
+ jmethodID id = getMethodID(env, clazz, methodName, signature, true);
if (id) {
res = env->CallStaticObjectMethodV(clazz, id, args);
if (env.exceptionCheckAndClear()) {
@@ -790,24 +813,25 @@ QJniObject QJniObject::callStaticObjectMethodV(jclass clazz,
}
/*!
- \fn template <typename T> T QJniObject::callMethod(const char *methodName, const char *sig, ...) const
+ \fn template <typename T> T QJniObject::callMethod(const char *methodName, const char *signature, ...) const
- Calls the method \a methodName with a signature \a sig and returns the value.
+ Calls the object's method \a methodName with \a signature specifying the types of any
+ subsequent arguments.
\code
- QJniObject myJavaString = ...;
+ QJniObject myJavaStrin("org/qtproject/qt/TestClass");
jint index = myJavaString.callMethod<jint>("indexOf", "(I)I", 0x0051);
\endcode
*/
template <>
-Q_CORE_EXPORT void QJniObject::callMethod<void>(const char *methodName, const char *sig, ...) const
+Q_CORE_EXPORT void QJniObject::callMethod<void>(const char *methodName, const char *signature, ...) const
{
QJniEnvironment env;
- jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig);
+ jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, signature);
if (id) {
va_list args;
- va_start(args, sig);
+ va_start(args, signature);
env->CallVoidMethodV(d->m_jobject, id, args);
va_end(args);
env.exceptionCheckAndClear();
@@ -820,7 +844,7 @@ Q_CORE_EXPORT void QJniObject::callMethod<void>(const char *methodName, const ch
Calls the method \a methodName and returns the value.
\code
- QJniObject myJavaString = ...;
+ QJniObject myJavaStrin("org/qtproject/qt/TestClass");
jint size = myJavaString.callMethod<jint>("length");
\endcode
*/
@@ -833,30 +857,29 @@ Q_CORE_EXPORT void QJniObject::callMethod<void>(const char *methodName) const
/*!
\fn template <typename T> T QJniObject::callStaticMethod(const char *className, const char *methodName, const char *signature, ...)
- Calls the static method with \a methodName with \a signature on class \a className with optional arguments.
+ Calls the static method \a methodName from class \a className with \a signature
+ specifying the types of any subsequent arguments.
\code
- ...
jint a = 2;
jint b = 4;
jint max = QJniObject::callStaticMethod<jint>("java/lang/Math", "max", "(II)I", a, b);
- ...
\endcode
*/
template <>
Q_CORE_EXPORT void QJniObject::callStaticMethod<void>(const char *className,
const char *methodName,
- const char *sig,
+ const char *signature,
...)
{
QJniEnvironment env;
jclass clazz = loadClass(className, env);
if (clazz) {
jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className),
- methodName, sig, true);
+ methodName, signature, true);
if (id) {
va_list args;
- va_start(args, sig);
+ va_start(args, signature);
env->CallStaticVoidMethodV(clazz, id, args);
va_end(args);
env.exceptionCheckAndClear();
@@ -882,29 +905,29 @@ Q_CORE_EXPORT void QJniObject::callStaticMethod<void>(const char *className, con
/*!
\fn template <typename T> T QJniObject::callStaticMethod(jclass clazz, const char *methodName, const char *signature, ...)
- Calls the static method \a methodName with \a signature on \a clazz and returns the value.
+ Calls the static method \a methodName from \a clazz with \a signature
+ specifying the types of any subsequent arguments.
\code
- ...
- jclass javaMathClass = ...; // ("java/lang/Math")
+ QJniEnvironment env;
+ jclass javaMathClass = env.findClass("java/lang/Math");
jint a = 2;
jint b = 4;
jint max = QJniObject::callStaticMethod<jint>(javaMathClass, "max", "(II)I", a, b);
- ...
\endcode
*/
template <>
Q_CORE_EXPORT void QJniObject::callStaticMethod<void>(jclass clazz,
const char *methodName,
- const char *sig,
+ const char *signature,
...)
{
QJniEnvironment env;
if (clazz) {
- jmethodID id = getMethodID(env, clazz, methodName, sig, true);
+ jmethodID id = getMethodID(env, clazz, methodName, signature, true);
if (id) {
va_list args;
- va_start(args, sig);
+ va_start(args, signature);
env->CallStaticVoidMethodV(clazz, id, args);
va_end(args);
env.exceptionCheckAndClear();
@@ -915,7 +938,7 @@ Q_CORE_EXPORT void QJniObject::callStaticMethod<void>(jclass clazz,
template <>
Q_CORE_EXPORT void QJniObject::callStaticMethodV<void>(const char *className,
const char *methodName,
- const char *sig,
+ const char *signature,
va_list args)
{
QJniEnvironment env;
@@ -923,7 +946,7 @@ Q_CORE_EXPORT void QJniObject::callStaticMethodV<void>(const char *className,
if (clazz) {
jmethodID id = getCachedMethodID(env, clazz,
toBinaryEncClassName(className), methodName,
- sig, true);
+ signature, true);
if (id) {
env->CallStaticVoidMethodV(clazz, id, args);
env.exceptionCheckAndClear();
@@ -934,11 +957,11 @@ Q_CORE_EXPORT void QJniObject::callStaticMethodV<void>(const char *className,
template <>
Q_CORE_EXPORT void QJniObject::callStaticMethodV<void>(jclass clazz,
const char *methodName,
- const char *sig,
+ const char *signature,
va_list args)
{
QJniEnvironment env;
- jmethodID id = getMethodID(env, clazz, methodName, sig, true);
+ jmethodID id = getMethodID(env, clazz, methodName, signature, true);
if (id) {
env->CallStaticVoidMethodV(clazz, id, args);
env.exceptionCheckAndClear();
@@ -951,10 +974,9 @@ Q_CORE_EXPORT void QJniObject::callStaticMethodV<void>(jclass clazz,
Calls the static method \a methodName on \a clazz and returns the value.
\code
- ...
- jclass javaMathClass = ...; // ("java/lang/Math")
+ QJniEnvironment env;
+ jclass javaMathClass = env.findClass("java/lang/Math");
jdouble randNr = QJniObject::callStaticMethod<jdouble>(javaMathClass, "random");
- ...
\endcode
*/
template <>
@@ -964,11 +986,11 @@ Q_CORE_EXPORT void QJniObject::callStaticMethod<void>(jclass clazz, const char *
}
template <>
-Q_CORE_EXPORT void QJniObject::callMethodV<void>(const char *methodName, const char *sig,
+Q_CORE_EXPORT void QJniObject::callMethodV<void>(const char *methodName, const char *signature,
va_list args) const
{
QJniEnvironment env;
- jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig);
+ jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, signature);
if (id) {
env->CallVoidMethodV(d->m_jobject, id, args);
env.exceptionCheckAndClear();
@@ -977,14 +999,14 @@ Q_CORE_EXPORT void QJniObject::callMethodV<void>(const char *methodName, const c
#define MAKE_JNI_METHODS(MethodName, Type, Signature) \
template <> Q_CORE_EXPORT Type QJniObject::callMethod<Type>(const char *methodName, \
- const char *sig, ...) const \
+ const char *signature, ...) const \
{ \
QJniEnvironment env; \
Type res = 0; \
- jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); \
+ jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, signature); \
if (id) { \
va_list args; \
- va_start(args, sig); \
+ va_start(args, signature); \
res = env->Call##MethodName##MethodV(d->m_jobject, id, args); \
va_end(args); \
if (env.exceptionCheckAndClear()) \
@@ -999,7 +1021,7 @@ template <> Q_CORE_EXPORT Type QJniObject::callMethod<Type>(const char *methodNa
\
template <> Q_CORE_EXPORT Type QJniObject::callStaticMethod<Type>(const char *className, \
const char *methodName, \
- const char *sig, \
+ const char *signature, \
...) \
{ \
QJniEnvironment env; \
@@ -1007,10 +1029,10 @@ template <> Q_CORE_EXPORT Type QJniObject::callStaticMethod<Type>(const char *cl
jclass clazz = loadClass(className, env); \
if (clazz) { \
jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, \
- sig, true); \
+ signature, true); \
if (id) { \
va_list args; \
- va_start(args, sig); \
+ va_start(args, signature); \
res = env->CallStatic##MethodName##MethodV(clazz, id, args); \
va_end(args); \
if (env.exceptionCheckAndClear()) \
@@ -1027,16 +1049,16 @@ template <> Q_CORE_EXPORT Type QJniObject::callStaticMethod<Type>(const char *cl
\
template <> Q_CORE_EXPORT Type QJniObject::callStaticMethod<Type>(jclass clazz, \
const char *methodName, \
- const char *sig, \
+ const char *signature, \
...) \
{ \
QJniEnvironment env; \
Type res = 0; \
if (clazz) { \
- jmethodID id = getMethodID(env, clazz, methodName, sig, true); \
+ jmethodID id = getMethodID(env, clazz, methodName, signature, true); \
if (id) { \
va_list args; \
- va_start(args, sig); \
+ va_start(args, signature); \
res = env->CallStatic##MethodName##MethodV(clazz, id, args); \
va_end(args); \
if (env.exceptionCheckAndClear()) \
@@ -1051,12 +1073,12 @@ template <> Q_CORE_EXPORT Type QJniObject::callStaticMethod<Type>(jclass clazz,
return callStaticMethod<Type>(clazz, methodName, Signature); \
}\
template <> \
-Q_CORE_EXPORT Type QJniObject::callMethodV<Type>(const char *methodName, const char *sig,\
+Q_CORE_EXPORT Type QJniObject::callMethodV<Type>(const char *methodName, const char *signature,\
va_list args) const\
{\
QJniEnvironment env;\
Type res = 0;\
- jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig);\
+ jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, signature);\
if (id) {\
res = env->Call##MethodName##MethodV(d->m_jobject, id, args);\
if (env.exceptionCheckAndClear()) \
@@ -1066,16 +1088,16 @@ Q_CORE_EXPORT Type QJniObject::callMethodV<Type>(const char *methodName, const c
}\
template <>\
Q_CORE_EXPORT Type QJniObject::callStaticMethodV<Type>(const char *className,\
- const char *methodName,\
- const char *sig,\
- va_list args)\
+ const char *methodName,\
+ const char *signature,\
+ va_list args)\
{\
QJniEnvironment env;\
Type res = 0;\
jclass clazz = loadClass(className, env);\
if (clazz) {\
jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName,\
- sig, true);\
+ signature, true);\
if (id) {\
res = env->CallStatic##MethodName##MethodV(clazz, id, args);\
if (env.exceptionCheckAndClear()) \
@@ -1086,13 +1108,13 @@ Q_CORE_EXPORT Type QJniObject::callStaticMethodV<Type>(const char *className,\
}\
template <>\
Q_CORE_EXPORT Type QJniObject::callStaticMethodV<Type>(jclass clazz,\
- const char *methodName,\
- const char *sig,\
- va_list args)\
+ const char *methodName,\
+ const char *signature,\
+ va_list args)\
{\
QJniEnvironment env;\
Type res = 0;\
- jmethodID id = getMethodID(env, clazz, methodName, sig, true);\
+ jmethodID id = getMethodID(env, clazz, methodName, signature, true);\
if (id) {\
res = env->CallStatic##MethodName##MethodV(clazz, id, args);\
if (env.exceptionCheckAndClear()) \
@@ -1116,21 +1138,23 @@ DECLARE_JNI_METHODS(Double, jdouble, "()D")
/*!
\fn QJniObject QJniObject::callObjectMethod(const char *methodName, const char *signature, ...) const
- Calls the Java object's method \a methodName with the signature \a signature and arguments
+ Calls the Java object's method \a methodName with \a signature specifying
+ the types of any subsequent arguments.
\code
- QJniObject myJavaString; ==> "Hello, Java"
- QJniObject mySubstring = myJavaString.callObjectMethod("substring", "(II)Ljava/lang/String;", 7, 10);
+ QJniObject myJavaString = QJniObject::fromString("Hello, Java");
+ QJniObject mySubstring = myJavaString.callObjectMethod("substring",
+ "(II)Ljava/lang/String;", 7, 11);
\endcode
*/
-QJniObject QJniObject::callObjectMethod(const char *methodName, const char *sig, ...) const
+QJniObject QJniObject::callObjectMethod(const char *methodName, const char *signature, ...) const
{
QJniEnvironment env;
jobject res = nullptr;
- jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig);
+ jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, signature);
if (id) {
va_list args;
- va_start(args, sig);
+ va_start(args, signature);
res = env->CallObjectMethodV(d->m_jobject, id, args);
va_end(args);
if (env.exceptionCheckAndClear()) {
@@ -1147,27 +1171,30 @@ QJniObject QJniObject::callObjectMethod(const char *methodName, const char *sig,
/*!
\fn QJniObject QJniObject::callStaticObjectMethod(const char *className, const char *methodName, const char *signature, ...)
- Calls the static method with \a methodName and \a signature on the class \a className.
+ Calls the static method \a methodName from the class \a className with \a signature
+ specifying the types of any subsequent arguments.
\code
- QJniObject thread = QJniObject::callStaticObjectMethod("java/lang/Thread", "currentThread", "()Ljava/lang/Thread;");
- QJniObject string = QJniObject::callStaticObjectMethod("java/lang/String", "valueOf", "(I)Ljava/lang/String;", 10);
+ QJniObject thread = QJniObject::callStaticObjectMethod("java/lang/Thread", "currentThread",
+ "()Ljava/lang/Thread;");
+ QJniObject string = QJniObject::callStaticObjectMethod("java/lang/String", "valueOf",
+ "(I)Ljava/lang/String;", 10);
\endcode
*/
QJniObject QJniObject::callStaticObjectMethod(const char *className,
const char *methodName,
- const char *sig,
+ const char *signature,
...)
{
QJniEnvironment env;
jobject res = nullptr;
jclass clazz = loadClass(className, env);
if (clazz) {
- jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName,
- sig, true);
+ jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className),
+ methodName, signature, true);
if (id) {
va_list args;
- va_start(args, sig);
+ va_start(args, signature);
res = env->CallStaticObjectMethodV(clazz, id, args);
va_end(args);
if (env.exceptionCheckAndClear()) {
@@ -1185,20 +1212,21 @@ QJniObject QJniObject::callStaticObjectMethod(const char *className,
/*!
\fn QJniObject QJniObject::callStaticObjectMethod(jclass clazz, const char *methodName, const char *signature, ...)
- Calls the static method with \a methodName and \a signature on class \a clazz.
+ Calls the static method \a methodName from class \a clazz with \a signature
+ specifying the types of any subsequent arguments.
*/
QJniObject QJniObject::callStaticObjectMethod(jclass clazz,
const char *methodName,
- const char *sig,
+ const char *signature,
...)
{
QJniEnvironment env;
jobject res = nullptr;
if (clazz) {
- jmethodID id = getMethodID(env, clazz, methodName, sig, true);
+ jmethodID id = getMethodID(env, clazz, methodName, signature, true);
if (id) {
va_list args;
- va_start(args, sig);
+ va_start(args, signature);
res = env->CallStaticObjectMethodV(clazz, id, args);
va_end(args);
if (env.exceptionCheckAndClear()) {
@@ -1219,10 +1247,8 @@ QJniObject QJniObject::callStaticObjectMethod(jclass clazz,
the returned Java object.
\code
- ...
- QJniObject myJavaString1 = ...;
+ QJniObject myJavaString = QJniObject::fromString("Hello, Java");
QJniObject myJavaString2 = myJavaString1.callObjectMethod<jstring>("toString");
- ...
\endcode
*/
@@ -1244,6 +1270,26 @@ QJniObject QJniObject::callStaticObjectMethod(jclass clazz,
*/
/*!
+ \fn template <typename T> T QJniObject::object() const
+
+ Returns the object held by the QJniObject as type T.
+ T can be one of \l {Object Types}{JNI Object Types}.
+
+ \code
+ QJniObject string = QJniObject::fromString("Hello, JNI");
+ jstring jstring = string.object<jstring>();
+ \endcode
+
+ \note The returned object is still kept live by this QJniObject. To keep the
+ object live beyond the lifetime of this QJniObject, for example to record it
+ for later use, the easiest approach is to store it in another QJniObject with
+ a suitable lifetime. Alternatively, you can make a new global reference to the
+ object and store it, taking care to free it when you are done with it.
+
+ \snippet jni/src_qjniobject.cpp QJniObject scope
+*/
+
+/*!
\fn template <typename T> QJniObject &QJniObject::operator=(T object)
Replace the current object with \a object. The old Java object will be released.
@@ -1297,12 +1343,14 @@ DECLARE_JNI_OBJECT_METHODS(jthrowable, "()Ljava/lang/Throwable;")
/*!
\fn template <typename T> void QJniObject::setStaticField(const char *className, const char *fieldName, const char *signature, T value);
- Sets the static field with \a fieldName and \a signature to \a value on class named \a className.
+ Sets the static field \a fieldName on the class \a className to \a value
+ using the setter with \a signature.
+
*/
template <>
Q_CORE_EXPORT void QJniObject::setStaticField<jobject>(const char *className,
const char *fieldName,
- const char *sig,
+ const char *signature,
jobject value)
{
QJniEnvironment env;
@@ -1311,7 +1359,7 @@ Q_CORE_EXPORT void QJniObject::setStaticField<jobject>(const char *className,
if (!clazz)
return;
- jfieldID id = getCachedFieldID(env, clazz, className, fieldName, sig, true);
+ jfieldID id = getCachedFieldID(env, clazz, className, fieldName, signature, true);
if (id) {
env->SetStaticObjectField(clazz, id, value);
env.exceptionCheckAndClear();
@@ -1321,15 +1369,16 @@ Q_CORE_EXPORT void QJniObject::setStaticField<jobject>(const char *className,
/*!
\fn template <typename T> void QJniObject::setStaticField(jclass clazz, const char *fieldName, const char *signature, T value);
- Sets the static field with \a fieldName and \a signature to \a value on class \a clazz.
+ Sets the static field \a fieldName on the class \a clazz to \a value using
+ the setter with \a signature.
*/
template <> Q_CORE_EXPORT void QJniObject::setStaticField<jobject>(jclass clazz,
const char *fieldName,
- const char *sig,
+ const char *signature,
jobject value)
{
QJniEnvironment env;
- jfieldID id = getFieldID(env, clazz, fieldName, sig, true);
+ jfieldID id = getFieldID(env, clazz, fieldName, signature, true);
if (id) {
env->SetStaticObjectField(clazz, id, value);
@@ -1343,8 +1392,8 @@ template <> Q_CORE_EXPORT void QJniObject::setStaticField<jobject>(jclass clazz,
Retrieves the value of the field \a fieldName.
\code
- QJniObject volumeControl = ...;
- jint fieldValue = volumeControl.getField<jint>("MAX_VOLUME");
+ QJniObject volumeControl("org/qtproject/qt/TestClass");
+ jint fieldValue = volumeControl.getField<jint>("FIELD_NAME");
\endcode
*/
@@ -1363,7 +1412,7 @@ template <> Q_CORE_EXPORT void QJniObject::setStaticField<jobject>(jclass clazz,
/*!
\fn template <typename T> void QJniObject::setStaticField(const char *className, const char *fieldName, T value)
- Sets the static field \a fieldName of the class named \a className to \a value.
+ Sets the static field \a fieldName of the class \a className to \a value.
*/
/*!
@@ -1461,24 +1510,27 @@ DECLARE_JNI_PRIMITIVE_FIELDS(Double, jdouble, "D")
/*!
\fn QJniObject QJniObject::getStaticObjectField(const char *className, const char *fieldName, const char *signature)
- Retrieves the object from the field with \a signature and \a fieldName on class \a className.
+
+ Retrieves a JNI object from the field \a filedName with \a signature from
+ class \a className.
\note This function can be used without a template type.
\code
- QJniObject jobj = QJniObject::getStaticObjectField("class/with/Fields", "FIELD_NAME", "Ljava/lang/String;");
+ QJniObject jobj = QJniObject::getStaticObjectField("class/with/Fields", "FIELD_NAME",
+ "Ljava/lang/String;");
\endcode
*/
QJniObject QJniObject::getStaticObjectField(const char *className,
const char *fieldName,
- const char *sig)
+ const char *signature)
{
QJniEnvironment env;
jclass clazz = loadClass(className, env);
if (!clazz)
return QJniObject();
jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName,
- sig, true);
+ signature, true);
if (!id)
return QJniObject();
@@ -1495,7 +1547,9 @@ QJniObject QJniObject::getStaticObjectField(const char *className,
/*!
\fn QJniObject QJniObject::getStaticObjectField(jclass clazz, const char *fieldName, const char *signature)
- Retrieves the object from the field with \a signature and \a fieldName on \a clazz.
+
+ Retrieves a JNI object from the field \a fieldName with \a signature from
+ class \a clazz.
\note This function can be used without a template type.
@@ -1505,11 +1559,11 @@ QJniObject QJniObject::getStaticObjectField(const char *className,
*/
QJniObject QJniObject::getStaticObjectField(jclass clazz,
const char *fieldName,
- const char *sig)
+ const char *signature)
{
QJniEnvironment env;
jobject res = nullptr;
- jfieldID id = getFieldID(env, clazz, fieldName, sig, true);
+ jfieldID id = getFieldID(env, clazz, fieldName, signature, true);
if (id) {
res = env->GetStaticObjectField(clazz, id);
if (env.exceptionCheckAndClear()) {
@@ -1526,53 +1580,57 @@ QJniObject QJniObject::getStaticObjectField(jclass clazz,
/*!
\fn QJniObject QJniObject::getStaticObjectField<jobject>(jclass clazz, const char *fieldName, const char *signature)
- Retrieves the \a jobject from the field with \a signature and \a fieldName on \a clazz.
+ Retrieves a JNI object for \c jobject from the static field \a fieldName with
+ \a signature from \a clazz.
*/
template <>
Q_CORE_EXPORT QJniObject QJniObject::getStaticObjectField<jobject>(jclass clazz,
const char *fieldName,
- const char *sig)
+ const char *signature)
{
- return getStaticObjectField(clazz, fieldName, sig);
+ return getStaticObjectField(clazz, fieldName, signature);
}
/*!
- \fn QJniObject QJniObject::getStaticObjectField<jobject>(jclass clazz, const char *fieldName, const char *signature)
+ \fn QJniObject QJniObject::getStaticObjectField<jobject>(const char *className, const char *fieldName, const char *signature)
- Retrieves the jobject from the field with \a signature and \a fieldName on class named \a className.
+ Retrieves a JNI object for \c jobject from the static field \a fieldName with
+ \a signature from class \a className.
*/
template <>
Q_CORE_EXPORT QJniObject QJniObject::getStaticObjectField<jobject>(const char *className,
const char *fieldName,
- const char *sig)
+ const char *signature)
{
- return getStaticObjectField(className, fieldName, sig);
+ return getStaticObjectField(className, fieldName, signature);
}
/*!
\fn QJniObject QJniObject::getStaticObjectField<jobjectArray>(jclass clazz, const char *fieldName, const char *signature)
- Retrieves the jobjectArray from the field with \a signature and \a fieldName on \a clazz.
+ Retrieves a JNI object for \c jobjectArray from the static field \a fieldName
+ with \a signature from class \a clazz.
*/
template <>
Q_CORE_EXPORT QJniObject QJniObject::getStaticObjectField<jobjectArray>(jclass clazz,
const char *fieldName,
- const char *sig)
+ const char *signature)
{
- return getStaticObjectField(clazz, fieldName, sig);
+ return getStaticObjectField(clazz, fieldName, signature);
}
/*!
- \fn QJniObject QJniObject::getStaticObjectField<jobjectArray>(jclass clazz, const char *fieldName, const char *signature)
+ \fn QJniObject QJniObject::getStaticObjectField<jobjectArray>(const char *className, const char *fieldName, const char *signature)
- Retrieves the jobjectArray from the field with \a signature and \a fieldName on the class named \a className.
+ Retrieves a JNI object for \c jobjectArray from the static field \a fieldName
+ with \a signature from class \a className.
*/
template <>
Q_CORE_EXPORT QJniObject QJniObject::getStaticObjectField<jobjectArray>(const char *className,
const char *fieldName,
- const char *sig)
+ const char *signature)
{
- return getStaticObjectField(className, fieldName, sig);
+ return getStaticObjectField(className, fieldName, signature);
}
/*!
@@ -1583,14 +1641,15 @@ Q_CORE_EXPORT QJniObject QJniObject::getStaticObjectField<jobjectArray>(const ch
\code
QJniObject stringArray = ...;
QJniObject obj = ...;
- obj.setField<jobjectArray>("KEY_VALUES", "([Ljava/lang/String;)V", stringArray.object<jobjectArray>())
+ obj.setField<jobjectArray>("KEY_VALUES", "([Ljava/lang/String;)V",
+ stringArray.object<jobjectArray>())
\endcode
*/
template <> Q_CORE_EXPORT
-void QJniObject::setField<jobject>(const char *fieldName, const char *sig, jobject value)
+void QJniObject::setField<jobject>(const char *fieldName, const char *signature, jobject value)
{
QJniEnvironment env;
- jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, sig);
+ jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, signature);
if (id) {
env->SetObjectField(d->m_jobject, id, value);
env.exceptionCheckAndClear();
@@ -1598,10 +1657,12 @@ void QJniObject::setField<jobject>(const char *fieldName, const char *sig, jobje
}
template <> Q_CORE_EXPORT
-void QJniObject::setField<jobjectArray>(const char *fieldName, const char *sig, jobjectArray value)
+void QJniObject::setField<jobjectArray>(const char *fieldName,
+ const char *signature,
+ jobjectArray value)
{
QJniEnvironment env;
- jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, sig);
+ jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, signature);
if (id) {
env->SetObjectField(d->m_jobject, id, value);
env.exceptionCheckAndClear();
@@ -1611,7 +1672,7 @@ void QJniObject::setField<jobjectArray>(const char *fieldName, const char *sig,
/*!
\fn QJniObject QJniObject::getObjectField(const char *fieldName) const
- Retrieves the object of field \a fieldName.
+ Retrieves a JNI object from the field \a fieldName.
\code
QJniObject field = jniObject.getObjectField<jstring>("FIELD_NAME");
@@ -1621,7 +1682,7 @@ void QJniObject::setField<jobjectArray>(const char *fieldName, const char *sig,
/*!
\fn QJniObject QJniObject::getObjectField(const char *fieldName, const char *signature) const
- Retrieves the object from the field with \a signature and \a fieldName.
+ Retrieves a JNI object from the field \a fieldName with \a signature.
\note This function can be used without a template type.
@@ -1629,11 +1690,11 @@ void QJniObject::setField<jobjectArray>(const char *fieldName, const char *sig,
QJniObject field = jniObject.getObjectField("FIELD_NAME", "Ljava/lang/String;");
\endcode
*/
-QJniObject QJniObject::getObjectField(const char *fieldName, const char *sig) const
+QJniObject QJniObject::getObjectField(const char *fieldName, const char *signature) const
{
QJniEnvironment env;
jobject res = nullptr;
- jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, sig);
+ jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, signature);
if (id) {
res = env->GetObjectField(d->m_jobject, id);
if (env.exceptionCheckAndClear()) {
@@ -1653,12 +1714,10 @@ QJniObject QJniObject::getObjectField(const char *fieldName, const char *sig) co
Sets the value of \a fieldName to \a value.
\code
- ...
QJniObject obj;
obj.setField<jint>("AN_INT_FIELD", 10);
- jstring myString = ...
+ jstring myString = ...;
obj.setField<jstring>("A_STRING_FIELD", myString);
- ...
\endcode
*/
@@ -1806,9 +1865,9 @@ bool QJniObject::isClassAvailable(const char *className)
Returns true if this instance holds a valid Java object.
\code
- QJniObject qjniObject; ==> isValid() == false
- QJniObject qjniObject(0) ==> isValid() == false
- QJniObject qjniObject("could/not/find/Class") ==> isValid() == false
+ QJniObject qjniObject; // ==> isValid() == false
+ QJniObject qjniObject(0) // ==> isValid() == false
+ QJniObject qjniObject("could/not/find/Class") // ==> isValid() == false
\endcode
*/
bool QJniObject::isValid() const
@@ -1818,7 +1877,6 @@ bool QJniObject::isValid() const
/*!
\fn QJniObject QJniObject::fromLocalRef(jobject localRef)
- \since 6.1
Creates a QJniObject from the local JNI reference \a localRef.
This function takes ownership of \a localRef and frees it before returning.
diff --git a/src/corelib/kernel/qjniobject.h b/src/corelib/kernel/qjniobject.h
index 2998c7b4e8..0f88695e73 100644
--- a/src/corelib/kernel/qjniobject.h
+++ b/src/corelib/kernel/qjniobject.h
@@ -58,9 +58,9 @@ class Q_CORE_EXPORT QJniObject
public:
QJniObject();
explicit QJniObject(const char *className);
- explicit QJniObject(const char *className, const char *sig, ...);
+ explicit QJniObject(const char *className, const char *signature, ...);
explicit QJniObject(jclass clazz);
- explicit QJniObject(jclass clazz, const char *sig, ...);
+ explicit QJniObject(jclass clazz, const char *signature, ...);
QJniObject(jobject globalRef);
~QJniObject();
@@ -69,19 +69,20 @@ public:
jobject object() const;
template <typename T>
- T callMethod(const char *methodName, const char *sig, ...) const;
+ T callMethod(const char *methodName, const char *signature, ...) const;
template <typename T>
T callMethod(const char *methodName) const;
template <typename T>
QJniObject callObjectMethod(const char *methodName) const;
- QJniObject callObjectMethod(const char *methodName, const char *sig, ...) const;
+ QJniObject callObjectMethod(const char *methodName, const char *signature, ...) const;
template <typename T>
- static T callStaticMethod(const char *className, const char *methodName, const char *sig, ...);
+ static T callStaticMethod(const char *className, const char *methodName,
+ const char *signature, ...);
template <typename T>
static T callStaticMethod(const char *className, const char *methodName);
template <typename T>
- static T callStaticMethod(jclass clazz, const char *methodName, const char *sig, ...);
+ static T callStaticMethod(jclass clazz, const char *methodName, const char *signature, ...);
template <typename T>
static T callStaticMethod(jclass clazz, const char *methodName);
@@ -89,13 +90,13 @@ public:
static QJniObject callStaticObjectMethod(const char *className, const char *methodName);
static QJniObject callStaticObjectMethod(const char *className,
const char *methodName,
- const char *sig, ...);
+ const char *signature, ...);
template <typename T>
static QJniObject callStaticObjectMethod(jclass clazz, const char *methodName);
static QJniObject callStaticObjectMethod(jclass clazz,
const char *methodName,
- const char *sig, ...);
+ const char *signature, ...);
template <typename T>
T getField(const char *fieldName) const;
@@ -107,35 +108,38 @@ public:
template <typename T>
QJniObject getObjectField(const char *fieldName) const;
- QJniObject getObjectField(const char *fieldName, const char *sig) const;
+ QJniObject getObjectField(const char *fieldName, const char *signature) const;
template <typename T>
static QJniObject getStaticObjectField(const char *className, const char *fieldName);
static QJniObject getStaticObjectField(const char *className,
const char *fieldName,
- const char *sig);
+ const char *signature);
template <typename T>
static QJniObject getStaticObjectField(const char *className,
const char *fieldName,
- const char *sig);
+ const char *signature);
template <typename T>
static QJniObject getStaticObjectField(jclass clazz, const char *fieldName);
- static QJniObject getStaticObjectField(jclass clazz, const char *fieldName, const char *sig);
+ static QJniObject getStaticObjectField(jclass clazz, const char *fieldName,
+ const char *signature);
template <typename T>
- static QJniObject getStaticObjectField(jclass clazz, const char *fieldName, const char *sig);
+ static QJniObject getStaticObjectField(jclass clazz, const char *fieldName,
+ const char *signature);
template <typename T>
void setField(const char *fieldName, T value);
template <typename T>
- void setField(const char *fieldName, const char *sig, T value);
+ void setField(const char *fieldName, const char *signature, T value);
template <typename T>
static void setStaticField(const char *className, const char *fieldName, T value);
template <typename T>
static void setStaticField(const char *className, const char *fieldName,
- const char *sig, T value);
+ const char *signature, T value);
template <typename T>
- static void setStaticField(jclass clazz, const char *fieldName, const char *sig, T value);
+ static void setStaticField(jclass clazz, const char *fieldName,
+ const char *signature, T value);
template <typename T>
static void setStaticField(jclass clazz, const char *fieldName, T value);
@@ -154,31 +158,33 @@ public:
private:
struct QVaListPrivate { operator va_list &() const { return m_args; } va_list &m_args; };
- QJniObject(const char *className, const char *sig, const QVaListPrivate &args);
- QJniObject(jclass clazz, const char *sig, const QVaListPrivate &args);
+ QJniObject(const char *className, const char *signature, const QVaListPrivate &args);
+ QJniObject(jclass clazz, const char *signature, const QVaListPrivate &args);
template <typename T>
- T callMethodV(const char *methodName, const char *sig, va_list args) const;
- QJniObject callObjectMethodV(const char *methodName, const char *sig, va_list args) const;
+ T callMethodV(const char *methodName, const char *signature, va_list args) const;
+ QJniObject callObjectMethodV(const char *methodName,
+ const char *signature,
+ va_list args) const;
template <typename T>
static T callStaticMethodV(const char *className,
const char *methodName,
- const char *sig,
+ const char *signature,
va_list args);
template <typename T>
static T callStaticMethodV(jclass clazz,
const char *methodName,
- const char *sig,
+ const char *signature,
va_list args);
static QJniObject callStaticObjectMethodV(const char *className,
const char *methodName,
- const char *sig,
+ const char *signature,
va_list args);
static QJniObject callStaticObjectMethodV(jclass clazz,
const char *methodName,
- const char *sig,
+ const char *signature,
va_list args);
bool isSameObject(jobject obj) const;