I am developing a Qt-based application for Android. In case the app is launched as a result of opening a file I need to pass it to the Qt application instance. I created a custom Java activity so as to implement this behavior:
public class MyActivity extends org.qtproject.qt5.android.bindings.QtActivity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
System.out.println("MyActivity::onCreate");
testMethod(123, "test");
Intent i = getIntent();
String act = i.getAction();
// ...
} // onCreate
private static native boolean testMethod(int param, String data);
}
public class MyActivity extends org.qtproject.qt5.android.bindings.QtActivity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
System.out.println("MyActivity::onCreate");
testMethod(123, "test");
Intent i = getIntent();
String act = i.getAction();
// ...
} // onCreate
private static native boolean testMethod(int param, String data);
}
To copy to clipboard, switch view to plain text mode
On the C++ side I have something like this:
#include <QDebug>
#include <jni.h>
jboolean testMethodImpl(JNIEnv *env, jobject obj, jint param, jstring jstr)
{
const char *utf8 = env->GetStringUTFChars(jstr, nullptr);
qDebug() << "testMethod got colled: " << param << utf8;
env->ReleaseStringUTFChars(jstr, utf8);
return true;
}
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*)
{
qDebug() << "JNI_OnLoad got called";
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
// Get jclass with env->FindClass.
jclass javaClass = env->FindClass("com/mycompany/mypackage/MyActivity");
if(!javaClass)
{
return JNI_ERR;
}
// Register methods with env->RegisterNatives.
static JNINativeMethod methodsArray[] =
{
{"testMethod", "(ILjava/lang/String;)Z", (void *)testMethodImpl}
};
if(env->RegisterNatives(javaClass, methodsArray, sizeof(methodsArray) / sizeof(methodsArray[0])) < 0)
{
return JNI_ERR;
}
return JNI_VERSION_1_6;
}
int main(int argc, char *argv[])
{
qDebug() << "Calling main()";
QGuiApplication app(argc, argv);
qDebug() << "main arguments:";
for (int i = 0; i < argc; ++i)
qDebug() << argv[i];
// ...
}
#include <QDebug>
#include <jni.h>
jboolean testMethodImpl(JNIEnv *env, jobject obj, jint param, jstring jstr)
{
const char *utf8 = env->GetStringUTFChars(jstr, nullptr);
qDebug() << "testMethod got colled: " << param << utf8;
env->ReleaseStringUTFChars(jstr, utf8);
return true;
}
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*)
{
qDebug() << "JNI_OnLoad got called";
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
// Get jclass with env->FindClass.
jclass javaClass = env->FindClass("com/mycompany/mypackage/MyActivity");
if(!javaClass)
{
return JNI_ERR;
}
// Register methods with env->RegisterNatives.
static JNINativeMethod methodsArray[] =
{
{"testMethod", "(ILjava/lang/String;)Z", (void *)testMethodImpl}
};
if(env->RegisterNatives(javaClass, methodsArray, sizeof(methodsArray) / sizeof(methodsArray[0])) < 0)
{
return JNI_ERR;
}
return JNI_VERSION_1_6;
}
int main(int argc, char *argv[])
{
qDebug() << "Calling main()";
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
qDebug() << "main arguments:";
for (int i = 0; i < argc; ++i)
qDebug() << argv[i];
// ...
}
To copy to clipboard, switch view to plain text mode
The C++ method (testMethodImpl) gets called, but it happens before the main() function is called, therefore the application object has not been created yet. I can't handle the data passed in, because the processing classes do not exist at that moment. So my question: how can we call the methods of Qt application instance from android.app.Activity::onCreate method?
Bookmarks