Qt on Android Episode 4 - How to prepare your Qt application for publishing on Android markets
erratum 2014-04-13: Updated Bundle Qt libs pros and cons.
After we’ve learned how to set up the development environment and how to use Qt on Android, it’s time to move forward and in this article we are going to learn about different deployment systems and how to sign the package in order to publish it in any Android markets.
Choosing the right deploying system
Qt Creator supports three deployment systems:
- Use Ministro service to install Qt
- Bundle Qt libs in APK
- Deploy local Qt libs to temporary directory
Use Ministro service to install Qt
Back in 2009, when I started this project, there were only a few devices out there with Android. Most of them had very limited free space (less than 100 Mb), so, using Qt statically or bundling Qt libs into the APK was out of the question, also back then Google Market had way more limited size than today (50Mb limit/apk). As you can see I was forced to invent Ministro. Even today most of the mid/low-end devices don’t have too much space!
How it works?
- Instead of bundling everything into your APK, your package will contain ONLY your application .so file(s), its needed resources and a list with all needed external libs.
- When your application starts, it tries to connect to Ministro service, if it fails it means that Ministro is not installed and it opens the Android Play for the user to install Ministro. After it successfully connects to Ministro, it sends the dependencies list.
- Ministro checks if these dependencies are already available, if not, then it downloads only the missing ones in a central secure location and it sends back to the application another list with all the needed libs that the application must load before it loads your qt application.
- The application loads the libs from Ministro’s location, then your application, then it continues the running process.
Now let’s see the advantages and disadvantages of using Ministro.
- Using Ministro, the user needs to download the Qt libs ONLY once. If the user downloads another Qt application, it will use the existing libraries. Of course if that application needs more libs, Ministro will download only those that are missing.
- Ministro can detect if the device armv5 CPU has VFP or if the device armv7 CPU has NEON and it can download libs specific to that device CPU. Even if your application is not built with these CPU features, just using Qt libs built with them will make it run faster (on armv5, VFP really makes the difference, it will be way much faster). Currently these libs are not available, but I intend to publish them starting with 5.4.
- Ministro can upgrade Qt libs, without you needing to release a new application.
- You can target all Android platforms with a single APK. Because most likely your application (.so) file(s) are not very big, they can easily fit into a single APK. If your application doesn’t do intensive computation you can use only armv5 .so files to target both armv5 and armv7 platforms, because even if your APK contains only armv5 libs, Ministro will download the Qt libs specific for your device.
- You can use your own Ministro sources with your own libraries. Basically you’ll need an HTTP/HTTPS server with a valid certificate and to create and upload Ministro’s repository to that server. Because there is a lot to tell on this topic, I’m going to create a wiki page with all the information you need about this topic.
- Some people don’t like Ministro because the users must install Ministro service once. There are lots of apps out there which require other services, if my mother can install and use Google Hangouts on an older Android version, which needs Google Play service to be installed manually, or MX Player that needs MX Player Codecs to be installed manually, I’m pretty sure she will be just fine with any Qt application which requires Ministro to be installed once.
- Ministro upgrades Qt libraries and it might break things. I’m very concerned on this topic! To address this problem Ministro uses a different location for every major Qt release e.g:
Even more, every source is using a Debian-like release scheme with three different repositories:
- unstable – this is a pre-release repository used by Qt Project/Necessitas developers to test a new release. Before a new SDK release is announced, this repository is used to push the new libs and test it before officially announcing it.
- testing – after all tests pass, the libs are moved from unstable to testing repository and then we announce them on https://groups.google.com/forum/#!forum/android-qt, http://lists.qt-project.org/pipermail/android-development and on http://mail.kde.org/pipermail/necessitas-devel. The new version will stay in testing repository for at least one month to give enough time for the developers to test their existing apps using the new libs. Additional updates will be released in testing repository and the period may be extended if any regressions are reported. A new update must stay at least two weeks in testing repository.
- stable – after testing repository is regression free, the libs are moved to stable repository. It is very important that testing repository is regressions free before it lands on stable because in ~7 days all Android Ministro users will be notified about the new release and it will be very unpleasant if the users apps do not run any more!
Using this scheme Ministro users have no regression in 4 years and 13 Necessitas releases and 5 Qt project releases!
As you can see Ministro is quite safe on this matter!
Bundle Qt libs in APK
This feature was added recently to Qt Creator. Beside your application and your resources, Qt Creator adds all Qt libraries that your application needs to run.
- The APK contains everything it needs to run.
- erratum 2014-04-13: The ability of including custom builds of Qt. Improves time-to-market as you don’t have to wait for official releases before you can get your crucial bug fix. There’s also no waiting period after a new version of Qt is released before you can deploy it with your application.
- erratum 2014-04-13: The Qt libraries are not updated behind your back, no worries about sudden regressions.
- erratum 2014-04-13: The libraries will be served with your package in the store’s main infrastructure, whereas the Ministro libraries are served in the Qt Project infrastructure. The latter has not been tested for very large download volumes, so at this point we do not know how well it can serve a hugely successful application.
- erratum 2014-04-13: If done through Google Play, the download goes through the regular mechanisms on the device, so it continues in the background when your user suspends it, with progress indication in the status bar, and it obeys your users’ settings regarding downloads and updates over a mobile data connection.
The APK is HUGE due to Qt libs which are pretty big (+40Mb/platform).erratum 2014-04-13: The APK is big comparing with the Ministro’s version, due to Qt files which are pretty big. Qt files can go slightly over 40Mb/platform if you are going to use all of Qt modules. Of course your application doesnt need all the modules, so, if your application uses only Qt Quick Controls + Qt SVG + Qt Multimedia + Qt Sensors + Qt XML modules, Qt files (libs + plugins + additional files) are ~20Mb/platform and your APK will be ~10Mb.
- All Qt libs must be unpacked!
So your application will need a lot of free space to run (+50Mb)erratum 2014-04-13: The APK is NOT deleted after you install the application, but is kept by Android O.S. in order to access its assets, so, don’t forget to to count its size as well. At first run, our application will extract Qt libs and plugin to the application home folder. To check exactly how much space your application uses, you have to go to Settings->Apps->your application, and check Total of the STORAGE section. I checked gallery Qt Quick Controls example with Qt SVG + Qt Multimedia + Qt Sensors + Qt XML and it occupies slightly over 35Mb. Currently only just a veryfew apps on Google Play require that much space to run.
- Most of the mid/low-end device users can’t afford to spend that much free space!
- Due to big size you can’t target more than one platform/apk. You must create an APK for every platform (armv5, armv7, x86).
This will be confusing for armv7 users because AFAIK Google Play will list your application twice, once for armv7 and once for armv5 (see MX Player Codecs). If my mother can install a simple application, I’m pretty sure that she doesn’t know what kind of CPU her phone has, actually I’m pretty sure that she doesn’t know what a CPU is or if her device has such a thing …erratum 2014-04-13: it seems that Google Play doesn’t list your application twice.
- Can’t use VFP on armv5 devices and NEON on armv7 devices.
- Qt libs can’t be shared by multiple Qt apps on the same device.
- Can’t get Qt libs updates automatically.
As you can see there is no perfect solution, the pros from Ministro go to cons of the Bundle Qt libs in APK and the cons go to pros :).
Deploy local Qt libs to temporary directory
This deploy system is used mostly by Qt hackers when hacking on Qt itself because it is the fastest way to deploy modified Qt libs on the device to test them. Do not use it in production!
In the end you are the one who will make the choice, I just wanted to present you all the advantages and disadvantages of every deployment system.
This is the last and most important step before publishing. In order to sign the package you’ll need a keystore and a self-signed certificate.
If you don’t have such a certificate, Qt Creator can help you to easily create one, you just need to press create button and fill the keystore and certificate fields, check the following image:
You can only upgrade your application with the same certificate you publish it with! So, make sure you are making backups of the keystore file.
If you already have a keystore, then just browse its location.
Next step is to switch your project to release and check sign package and open package location after build, check the following image:
After you’ve pressed run button, in a few moments Qt Creator will open the location where your package was built and signed, be sure you are choosing the signed one (QtApp-release.apk)! Check the following image:
That’s all folks, see you next time when will see how to use JNI to extend our Android applications.