Qt on Android Episode 1 - How Qt on Android began and how it works
Update: Qt on Android Episode 2 is available here
Update2: Here you can read also the Chinese version, thanks goes to Foruok.
I’d like to start a new series of blog posts focused on Qt on Android.
The first article is about how it began, how it works, the current status, what to expect from 5.2 and what are my plans for 5.3. In the next article I’ll focus on development setup for Android.
Let’s get started:
How did it begin?
In June 2009 I joined ROUTE 66 as a senior Linux developer. My first task was to port the navigation engine on Android. Back then Google hadn’t yet released any NDK officially, so I had to create one of my own from Android sources.
Shortly after, I managed to have a working engine running on Android. I began to love Android but something was missing, something that I cared a lot about. That something was Qt, my favorite framework. That was what was missing! And I said to myself that I had to do something about it.
In October 2009 Nokia (yep, Qt was owned by Nokia back then, what days …) announced the Lighthouse project. The Lighthouse project was created to allow developers to easily port Qt to (almost) any platform.
In late December 2009 (I think it was after Christmas) I had enough free time to begin the port. I also chose to use the Lighthouse project even if it was a very young research project. As far as I know my Android port was the first port that used Lighthouse. Just after a month (in January 2010), I saw the first graphics rendered by Qt on my phone. The feeling was fantastic!
A few months later, after Qt was in a good shape, I began the work on a Qt Creator plugin and on Ministro. The Qt Creator plugin enables the user to manage, develop, deploy, run & debug Qt applications on Android Devices/Emulator very easily.
Even if almost everything was in place, still not too many people wanted to use it because they had to compile everything manually. Then I decided to do something about it.
So, in 2011, a few weeks after Nokia announced their big strategy shift, I announced the first usable SDK for Android. This is how the Necessitas project began and after it become a huge success, I decided to join KDE and to continue the project under the KDE umbrella. Why KDE? Well, because we share the same goal: to keep Qt powerful and free for everyone. Also I could use their fantastic infrastructure to distribute Qt libs.
The very first SDK release was Linux only. Soon Ray Donnelly contacted me and ported the SDK to Windows and Mac. If you are using Necessitas (and Qt5 Android SDK) on any of these platforms, he is the guy you have to thank!
Together with Ray and other people, we’ve managed to do more and more releases of the Necessitas SDK.
Because the Qt Creator plugin was an immense success, I upstreamed the plugin in 2012, when Qt was still owned by Nokia!
In November 2012, I contributed the Android port to Qt Project for Qt 5 integration. Here I’d like to make some clarifications: ONLY Qt 5 is developed under the Qt Project umbrella. Qt 4 is still owned by KDE as Necessitas project.
Let’s see how Qt on Android broadly works. I’m not going to go way too deep in details but enough for you to have an idea how it works.
As I wrote previously, the port is based on the Lighthouse project. Lighthouse (now re-branded as QPA) is the platform abstraction layer for Qt. Basically this layer sits between Qt and the platform, making the porting pretty easy. Because Android applications are written in Java, and it is impossible to connect the Qt event loop to Android’s event loop, I had to move the Qt main event loop to another thread. If you want to extend your application keep in mind the fact that the Qt event loop and Java UI are running on different threads. Even after Google added the NativeActivity, it was impossible to use it, mostly because it didn’t expose all the features we need in Qt.
A Qt for Android application consists of two big parts:
- The native part, containing one or more .so files, which are actually your Qt application. If you choose to bundle Qt libraries, it will contain also these libs.
- Android specific part. This part contains the followings sub-parts:
- Android manifest. This is the entry point of your application. Android uses this file to decide which Application/Activity to start, it contains the application permissions, declares the minimum of the Android API that application needs, etc.
- Two Java classes which load the dependencies and your application. They are also a part of the Java bridge between Qt QPA and the Android world.
- Ministro service .aidl files. These are two interfaces used to communicate with Ministro service. Ministro service is one of the deployment solutions (will write more about that later).
- OIther resources, e.g. assets, strings, images, etc.
All these parts are bundled in a single package which represents your final application. Now lets see how those parts works together.
When your application starts, Android uses the manifest file to run an activity. This activity (which is a custom activity) is a small part of the magic in the Java world of your application. To be able to update Qt libs without breaking the existing application, the Java part is split in two: a very small part which ships together with your application (a part of it) and another part (a Java library, a .jar file) which contains all the logic for the QPA plugin.
The first Java part that is shipped with your application is responsible for finding the missing libs (Qt and Java) and to load them. It also forwards all the events (touch, application states changes, screen changes, etc.) to the second Java part.
The second Java part is responsible for communicating with Qt. It contains all the logic needed by the Android QPA plugin, e.g. the creation and management of the drawing surface, virtual keyboard handling, and so on.
So, the (first) Java part finds and loads all the missing libs and your application and it forwards all the events to the second part, but how does your “main” method get called? Well, the QPA plugin does that. No, I’m not insane! And yes the QPA plugin is loaded before your application starts (actually is loaded even before your application is loaded 🙂 ).
Ok, let me try and explain why I had to come to such a crazy design.
My dream was to find a way so that the developers could just compile their existing Qt applications for Android, so I had to find a way to call the “main” method (I didn’t want to force you to create other main entry methods for your application, similar to the “WinMain” thing 🙂 ).
The problem is that in order to call a method from Java, someone has to register that method first, otherwise you can’t call it, here the QPA comes in the scene. After the QPA plugin is loaded, it registers a few native function which are used by the Java part to make calls in the native world. After the Java part finishes to load all the libs and your application, it just calls “startQtApplication“ native method which was registered by the QPA plugin earlier. This method searches for “main” method symbol, creates another thread and runs the “main” method from within that thread. It must create another thread because calling “main” method blocks the caller until it exists and we must keep the Android UI thread free to allow the Android event loop to run.
In a later article, I will cover how to use JNI to do calls from/to Java to/from native (C/C++) world.
Finally, have a look at the current status of Qt on Android, what you’ll get in Qt 5.2 and what are the plans for Qt 5.3 for Android.
Qt Essentials status:
Module |
Qt 5.1 |
Qt 5.2 |
Qt 5.3 |
Qt Core |
missing system semaphores and shared memory |
shared memory is on my TODO list |
|
Qt Multimedia |
video and audio works, missing camera support |
brings camera support |
ATM no other plans |
Qt Network |
missing SSL support |
brings SSL support |
ATM no other plans |
|
|
|
|
Qt Quick Controls (erratum) |
missing android native style |
missing android native style |
on my TODO list |
Qt SQL |
only sqlite is provided by Qt-Project SDK |
||
Qt WebKit & Qt WebKitWidgets, Qt WebEngine |
missing |
There is hope for Qt WebEngine |
|
Qt Widgets |
missing android native style |
brings android native style |
ATM no other plans |
Qt GUI, QML, Quick,Quick Layouts, Test |
just works |
Qt Add-Ons status:
Module |
Qt 5.1 |
Qt 5.2 |
Qt 5.3 |
Qt Android Extras |
missing |
additional functionality for development on Android |
android services/binder support is on my TODO list |
Qt Bluetooth |
missing |
on my TODO list |
|
Qt NFC |
missing |
on my TODO list |
|
Qt Positioning |
missing |
on my TODO list |
|
Qt D-Bus |
missing, android uses the binder IPC. |
Missing, but as I said Qt will have something similar for Android |
|
Qt Sensors |
commonly used sensors |
more sensors added |
ATM no other plans |
Qt PrintSupport |
missing, no native print support on Android |
||
Qt OpenGL |
limited to one top level widget, can’t mix QGLWidget with other QWidget(s) |
there is hope to use one more top level widget can mix a single QGLWidget with other QWidgets |
|
Qt SerialPort |
missing |
support added |
ATM no other plans |
Qt Concurrent, Declarative, GraphicalEffects, ImageFormats, Script, ScriptTools, SVG, XML, XMLPatterns
|
just works |
Thank you for your time.
See you next time when we’ll discuss how to setup the development for Android.
This post is hugely interesting. I’m looking forward for your next post.
Agree with all the kind words here. Can’t wait your article about JNI, hope that will help me to make working solution for vibrator on clear C++/JNI.
Awesome article. Is also pretty awesome that you are working for KDAB, too. Congratulations to all parties for this release. I just hope we will see open source Qt applications in the stores (remember there is F-droid for open source stuff) so they can act as a demo, and source of inspiration.
Yep, you are right! Working for KDAB is indeed awesome 😉 !
Writing great code is awesome and when you write such nice articles that explain how it all works, that is even nicer. Thanks you very much.
Awesome! Really looking forward to work with Qt+Android again, after KF5!!
\o/
This is quite a acomplishment. I hope Google itself can one day get behind Qt as a tier 1 SDK.
Question about QT libs. If you have more then one QT app do they share the same libraries, can the QT libs be part of the system lib or does each app package its own QT libs.
It these apps are using Minsitro, then yes, they will share the same Qt libs. As I said I’ll come with more information about this topic on a later episode.
Thank you all for your kind words and compliments!
Hi,
Is there anywhere I can find the information on how to set the “android native style” in Qt 5.2 beta? I can’t seem to find it anywhere…
Thanks!
You don’t need to do anything special. Any Qt application that uses Ministro will automatically use android native style.
Is not fully ready in beta, you’ll need to wait for rc.
If you still want to try it, you’ll need to use a (still) unreleased version of Ministro, check: http://lists.qt-project.org/pipermail/android-development/2013-October/000172.html .
Thanks a lot, Bogdan!
Hi BogDan,
nice to see you in KDAB doing all this. 🙂
By the way, QtSerialPort is supposed to work on Android in Qt 5.2, at least to a good extent. Please report the missing things if you find some.
We have added some relevant changes.
Cheers,
Laszlo
Fixed!
Thanks!
” Just after a month (in January 2010), I saw the first graphics rendered by Qt on my phone. The feeling was fantastic! ”
Sure it must have been fantastic , being the first one to run Qt on Android…
and special thanks for enabling thousands of users like us to write Qt apps on Android 🙂
Respect!!!
And Big THX for your commitment!
You have done some amazing work with Qt for Android! It has become a pleasure to use and I’m looking forward to the planned features. Thanks for all your great work!
Regarding the issue with the OpenGL limitation to one top level widget, so that you can’t mix QGLWidget with other QWidgets, I figured that a great alternative is to create the GUI using QtQuick and QtQuick.Controls and present the 3D content with Qt3D. QtQuick and Qt3D play nicely together on Android, and because the QML Viewport element renders to a framebuffer that is passed to QtQuick, it circumvents the limitation of only having one top-level OpenGL view. (I might have missed out on some technical details, but it works for sure.)
My pet project depends on your work. Thanking you is not enough for me.
Very sorry to see that QtWebkit isn’t supported in Qt5.2 for Android, even though there were hints in the comments for Qt5.1 that it might be supported for Qt5.2.
Can you comment on the reasons for this?
Note: I’m trying (unsuccessfully) to build QtWebkit for Android. I had a product design which would require it, and without it I won’t be able to use Qt at all.
Mostly because QtWebKit requires icu library.
Hi,
Thanks for this article and the fanstastic work.
I currently working with Qt on Android and I really need the QtSerialPort support on Android, you mention that the support will be effective on the version 5.2 of Qt. For the moment the support in not present on Qt 5.2 Beta, what about the support on the final Qt 5.2 release ?
Thanks for your comment
Hi,
Please check with Laszlo Papp, it was not implemented by me.
OK, well noted. Thanks
Thanks Bogdan for such a powerful piece of work. Can’t wait to play with it.
Hi Bogdan,
Thank you very much for your works for Qt-android support and this article.
By the way, could you tell me whether the camera support is included in the latest Qt(I mean Qt 5.2.0 beta1) or not?
I’m checking the example applications contained in the Qt 5.2.0 beta1, but couldn’t find any working camera application yet.
Thanks in advance.
It should be, make sure you are adding the right permissions to your application manifest file.
Thank you for quick reply.
I had a small progress.
After I added the “android.permission.CAMERA” in the manifest file of the ‘camera’ example, logcat says it succeeded to open the camera device.
However, there is no image shown on the screen, and logcat reports a lot of errors about interaction with the camera device. (FYI. I’m testing on a Nexus 7 2013)
But I think those are camera specific problems, not Qt-android.
Thank you!
Hmm … strange. Plase use https://bugreports.qt-project.org/ and report this issue, we’ll look at it.
QTBUG-34484 is very similar with my situation.
Bogdan,
I’d like to thank you for the great job you are doing and wish you all the best.
Any plan for support in app purchase?Besides, how could we get the default location of android(image, music and so on)
AFAIK there are no generic API for in app purchase, maybe we’ll add it to android extras, Also you can do it yourself by extending your Qt application with some custom java classes (I’ll write an article about this soon, so keep an eye to KDAB’s blog page 🙂 ).
Regarding QStandardPaths (which provides locations of images, music, etc.) it is a pending patch for Qt 5.2.1 here https://codereview.qt-project.org/#change,70575 .
Thanks for your reply, looking forward to read your next post.Please post it on http://planet.qt-project.org/ too if you can, this should let more people know about how to design their in app purchase class.
The article should be posted also there.
I just searched for “Qt on Android Episode” on http://planet.qt-project.org/ and I found my last article. The first one is not there anymore because probably it is too old.
Hello, do you think that Qt should not be sold/transfered to Digia? If so, which company would you want to acquire Qt project? (Could it be Google? :D)
—
Also someone say that Digia wants to change the license policy from gpl to something else of Qt project (like QPL). Is this true?
—
And a suggestion: QAnimation framework on Android is not really smooth. Please fix this. (Not problem with one widget. But if you try to animate 5-6 widgets at the same time, you will correct this issue(?))
—
Finally, thanks you so much. Really great work. Keep going!
– IMHO Qt-project is more open than other Google projects (e.g. Android).
– No! They can’t change the license! Check: http://www.kdab.com/be-free-qt-on-android/
– Well, you should try QML instead.
Hi, BogDan Vatra:
here is the Chinese version of Qt on Android Episode 1, http://blog.csdn.net/foruok/article/details/18697377。
Because I don’t have your email, I’ll post the link below your posts. Here is my email: foruok@163.com, if necessary, please contact me.
Thanks for your work, it simplified porting Qt aps to Android considerably. We develop one Qt app too and now we have linux and windows port, thanks to Qt. We want android port too, but without webkit it is imposible. Please please we are waiting for Qt5.3 🙂
Hello,
Will bluetooth supported for both android and windows ?
thanks.
I don’t know about windows, but bluetooth supported for Android should be part of 5.3
Hi, you affirm that in Qt 5.2, Qt SerialPort was supported for Android platform, but I failed trying compile a code with it.
Well, I didn’t list it for the first time, but Laszlo Papp ping me that is working ok.
Please check with him for more information or open an issue using https://bugreports.qt-project.org/
Hello Bogdan,
I appreciate your excellent blog articles and I am really getting into this. I’m interested in research on the possibility of porting some of our software to Android. We rely heavily on the Qt Framework and also need support for Bluetooth. I just checked out the Qt 5.3 release timeline. Can I expect Qt 5.3 for Android to be released according to the same main Qt release timeline? So also around the middle of May? Thanks for taking your time to answer my question.
Cheers,
..Ben
Qt for Android is the same with “main” Qt:).
Hello!
thanks for all your work!
I’m developing a little QtQuick App that I want to run on Android.
It looks like Qt5.3 will not support native Android style in any way, is that true? Then I tried ministro, but it seems that it doesn’t support native Android style on QtQuick either. That’s making me very sad. 🙁
Please tell me that you are still working on this, or that someone somewhere is working on this. I mean I’m using the brandnew Qt5.3 snapshot and Qt’s support for native styles on mobile is like Java’s support of native styles on the Desktop: terrible!
I’d love to get an update as to what’s the state of the matter, and what we can expect in the near/far future…
Maybe you can describe some of the roadblocks, too.
Maybe we can get a new blog entry on this?!
I’d really appreciate this! Thanks!
Proper Android look&feel for QtQuick will come in 5.4.
Is QT viable to be used as an application base for Android? I’d like to develop Android apps, but I’d prefer to use C++.
Yes it is! Qt is the only C++ framework that you can use to create GUI apps on Android.
Hi BogDan,thanks for all your work!
I am trying building a Html5 Application.It run well on pc. But when I built it to Android and IOS ,the following error occurred:
Project ERROR: Unknown module(s) in QT: webkit webkitwidgets.
From this paper,webkit is not supported on Android now.How about IOS?
my dev environment is:
mac Qt 5.2.1 (Clang 5.0 (Apple), 64 bit)
windows qt 5.3.1 (MSVC 2010,32 bit)
hi, can I get the libraries for qt serial port support on android