Android deployment with Ministro
-
Perhaps the way I try is not be best.
What I want to do, is to install once all needed Qt libs so I can later only install new APK with application upgrades.
==> This way the APK will only need 1MB instead of 20MB !
Do you have a better solution?
I have to do this on about 50 devices!
I've have try to copy Qt Libs on device in /data/local/tmp/qt, but this don't work...
Application and/or android didn't search in this location. -
@KroMignon
java.lang.UnsatisfiedLinkError: No implementation found for void com.geocept.android.NativeFunctions.focusWindow()
you didn't register your native JNI methods?!?
-
I do...
It works fine when I use Bundle Qt libraries in APK as Qt Deployment strategy.
I haven't change any line of code between the two APK generation.With Use Ministro service to install Qt, the application crash
-
@raven-worx said in Android deployment with Ministro:
you didn't register your native JNI methods?!?
I do register them with following code:
//create a vector with all our JNINativeMethod(s) static JNINativeMethod methods[] = { { "focusWindow", "()V", (void *)focusWindow }, }; // this method is called automatically by Java after the .so file is loaded JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* /*reserved*/) { JNIEnv* env; // get the JNIEnv pointer. if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) return JNI_ERR; // search for Java class which declares the native methods jclass javaClass = env->FindClass("com/geocept/android/NativeFunctions"); if (!javaClass) return JNI_ERR; // register our native methods if (env->RegisterNatives(javaClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) { return JNI_ERR; } return JNI_VERSION_1_6; }
Is there a way to made "incremental updates" with APK?
I install first a full featured APK then only APK without the Qt libs? -
@KroMignon
i suspect that there is still something wrong in your code/project-setup...Did you try to debug and step through in the call to
JNI_OnLoad()
?
Also where is this method defined? What kind of library is this?
Note that JNI_OnLoad() isn't loaded in Qt plugins (QQmlExtensionPlugin, ...) -
Did you try to debug and step through in the call to JNI_OnLoad()?
Also where is this method defined? What kind of library is this?
Note that JNI_OnLoad() isn't loaded in Qt plugins (QQmlExtensionPlugin, ...)I have picked JNI_OnLoad() usage from a presentation made by BogDan Vatra on QtCon 2016 ==> which was based on Qt 5.7
This presentation was called Practical Qt on Android JNI -
@KroMignon
JNI_OnLoad()
is only called when the library is loaded usingSystem.loadLibrary()
(Java method). Which isn't used when loading Qt plugins.
Thats why i asked what kind of library yours is. -
I use this to call C++ functions from Java, for example to be informed about Battery and WIFI level (which are got with an Android/Java BroadcastReceiver).
I don't understand why this works when Qt libs in APK and don't work when using Ministro...
-
@KroMignon
again: what is this library? Is this a simple default library linked to your application or is it a plugin?
How did you (exactly) add this library to your APK?I guess at the time you are trying to call the native method the method isn't registered yet. And set a breakpoint in your
JNI_OnLoad()
, as i already suggested. If the crash occurs before the breakpoint is hit, then this is your problem.If thats the case you can try to create the Java notification callback once you are sure that the methods have been registered successfully. You could set a Java variable at the end of
JNI_onLoad()
for example. -
This is in my application, there no external library, other than Qt.
This JNI_OnLoad() function is in a C++ class in my App project. The file name is JniInterfaces.cpp.
The function signature is:... static void focusWindow(JNIEnv * /*env*/, jobject /*obj*/) { if(HandheldInit::exists() && qGuiApp->focusWindow() != Q_NULLPTR) { QTimer::singleShot(0, qGuiApp->focusWindow(), SLOT(raise())); } } //create a vector with all our JNINativeMethod(s) static JNINativeMethod methods[] = { { "focusWindow", "()V", (void *)focusWindow }, }; // this method is called automatically by Java after the .so file is loaded JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* /*reserved*/) { ... } // See BogDan Vatra presentation at Qt Con 2016 ...
-
@KroMignon
ok i give up....
I am on hold until you answer the questions i asked. I wont ask a third time.... -
@raven-worx: sorry but there is no other library than Qt libraries...
I don't understand your question!
JNI_OnLoad() is in my application Project, focusWindow() also.
The Java code also.
There is no library!!! -
@KroMignon said in Android deployment with Ministro:
There is no library!!!
@KroMignon said in Android deployment with Ministro:
// this method is called automatically by Java after the .so file is loaded
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* /reserved/)
{ ... } // See BogDan Vatra presentation at Qt Con 2016You said it's working when you don't use Ministro but bundle the Qt libs with the APK.
But even then theJNI_OnLoad()
wouldn't be called, since you implemented JNI_OnLoad() not in a library. -
@raven-worx: the Qt Project create a library, called libNavDispatchHandheld.so, this is in the APK in /lib/armeabi-v7a.
Is this your are talking about?
And in this lib, which contains my C++ classes, is the JNI_OnLoad() function. -
@raven-worx: just to pass this annoying question about JNI. I have made a simple test, on which I removed all JNI functions (from Java => C++)
This also didn't work.
I've got an system error which indicates Ministro not available. But I have installed it (App-Info say it is v10.5).Is Qt5.7.1 not supported by Ministro?
I there a way to generate APK with all needed Qt stuff and then just do "upgrades" with my libs/qml/whatever ?
I'm a big Qt enthusiast, but it is very discouraging and sad to have the feeling to have to battle agains the System and not to work with it :(
-
@KroMignon said in Android deployment with Ministro:
just to pass this annoying question about JNI. I have made a simple test, on which I removed all JNI functions (from Java => C++)
This also didn't work.same error/exception?!?!
-
@raven-worx : no, there is an Android Popup which says I have to install Ministro... Which is already installed! ==> v10.5
-
@raven-worx : I've got an answer from BogDan Vatra, in fact Ministro does not support Qt 5.7.x
This is why nothing works when generating APK with Ministro.Qt5.7.x support will be added some time later. This is a bad news for me... I can't wait for a Ministro update.
So I found a workaround, I give it here, perhaps this could help someone else.
I have create a APK with Qt lib included, in release mode but not signed.
From this APK, which is in fact a ZIP archive, I've extract all Qt specific stuff:- assets/--Added-by-androiddeployqt--/*
- lib/armeabi-v7a/libplugins_*
- lib/armeabi-v7a/libqml_*
- lib/armeabi-v7a/libQt5*
- lib/armeabi-v7a/libgnustl_shared
I copy those files on device, into internal storage.
Then, I generate new APK (same configuration: release, with Qt libs and not signed).
To generate the update APK, I remove from this the Qt specific stuff (so APK size is now less than 2MB).
I transfer this APK on device, on device side I insert missed Qt libs into.
Then I start APK installation on device.This a very dirty way to do it, but it WorksForMe(TM)