Android: Add some developer documentation to AndroidBackendRegister
A quick blurb to explain the usecase and limitations of AndroidBackendRegister, meant for future developers. Also documents the two public-facing functions, getInterface() and callInterface(). Change-Id: I79f07d4a19fdb1f4a53529ab42a8663999759f85 Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
This commit is contained in:
parent
c2ec20b226
commit
43e52253d5
@ -19,6 +19,57 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(lcAndroidBackendRegister)
|
||||
|
||||
/*
|
||||
\internal
|
||||
|
||||
This class is used to [un]register QJniObjects which implement specific interfaces. These
|
||||
objects can then be fetched or directly called by using that interface.
|
||||
|
||||
This is intended to decouple the Qt C++ code from the underlying Java implementation, as Qt now
|
||||
has multiple separate usecases, each of which may have different implementations and support
|
||||
different features.
|
||||
|
||||
To use this register, the interface must be declared as a JNI class via Q_DECLARE_JNI_CLASS:
|
||||
|
||||
Q_DECLARE_JNI_CLASS(ImaginaryInterface, "org/qtproject/qt/android/ImaginaryInterface")
|
||||
|
||||
Where ImaginaryInterface is a Java interface like this:
|
||||
|
||||
@UsedFromNativeCode
|
||||
interface ImaginaryInterface {
|
||||
void doSomething(int imaginary, int imaginary2);
|
||||
}
|
||||
|
||||
After that, the features provided by that interface can be used in the C++ code in two ways:
|
||||
|
||||
Use the convenience method callInterface() to call a method directly:
|
||||
|
||||
AndroidBackendRegister *reg = QtAndroid::backendRegister();
|
||||
int imaginary, imaginary2;
|
||||
reg->callInterface<QtJniTypes::ImaginaryInterface, void>("doSomething", imaginary, imaginary2);
|
||||
|
||||
Or get the QJniObject directly and use it as you would any other QJniObject:
|
||||
AndroidBackendRegister *reg = QtAndroid::backendRegister();
|
||||
auto imaginary = reg->getInterface<QtJniTypes::ImaginaryInterface>();
|
||||
// ... do whatever with QJniObject
|
||||
|
||||
In order to register a new interface on the Java side, the BackendRegister class must be used,
|
||||
with its native functions registerBackend() and unregisterBackend():
|
||||
|
||||
BackendRegister.registerBackend(ImaginaryInterface.class, imaginaryInterfaceObject);
|
||||
|
||||
and
|
||||
|
||||
BackendRegister.unregisterBackend(ImaginaryInterface.class);
|
||||
|
||||
Note that only one object can be registered for each interface. If multiple objects are
|
||||
registered, only the latest one is kept. Thus, you only need to declare the interface you want
|
||||
to unregister, not the object that implements the interface as well.
|
||||
|
||||
If the interface needs to be available as soon as possible, it should be registered immediately
|
||||
after Qt has started, by using the QtNative app state listener functionality.
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
using ValidInterfaceType = std::enable_if_t<std::is_base_of_v<QtJniTypes::JObjectBase, T>, bool>;
|
||||
|
||||
@ -27,6 +78,13 @@ class AndroidBackendRegister
|
||||
public:
|
||||
static bool registerNatives();
|
||||
|
||||
/*
|
||||
\internal
|
||||
|
||||
Returns a QJniObject which is registered for the given interface.
|
||||
Requires the type of the requested interface to be registered via
|
||||
Q_DECLARE_JNI_CLASS. (see ValidInterfaceType).
|
||||
*/
|
||||
template <typename T, ValidInterfaceType<T> = true>
|
||||
[[nodiscard]] T getInterface()
|
||||
{
|
||||
@ -39,6 +97,14 @@ public:
|
||||
typename std::disjunction<std::is_base_of<QJniObject, Object>,
|
||||
std::is_base_of<QtJniTypes::JObjectBase, Object>>;
|
||||
|
||||
/*
|
||||
\internal
|
||||
|
||||
Convenience function that calls getInterface<Interface>() and then QJniObject::callMethod()
|
||||
on the resulting object, forwarding the rest of the parameters to that function.
|
||||
|
||||
If the interface is not registered, a warning is printed and an empty object is returned.
|
||||
*/
|
||||
template <typename Interface, typename Ret, typename... Args,
|
||||
ValidInterfaceType<Interface> = true>
|
||||
auto callInterface(const char *func, Args... args)
|
||||
|
Loading…
x
Reference in New Issue
Block a user