Qt on Android Episode 1

Update: Qt on Android Episode 2 is available here

Update2: Here you can read also the Chinese version, thanks goes to

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

missing android native style

brings android native style

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.

Share on FacebookTweet about this on TwitterShare on Google+
m4s0n501

49 thoughts on “Qt on Android Episode 1

    • 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.

  1. 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.

  2. 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.

  3. 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.

  4. 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!

  5. 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

  6. ” 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 :-)

  7. 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.)

  8. 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.

  9. 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

  10. 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.

      • 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!

  11. 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!

  12. 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 :)

  13. Hi, you affirm that in Qt 5.2, Qt SerialPort was supported for Android platform, but I failed trying compile a code with it.

  14. 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

  15. 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!

  16. 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++.

  17. 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)

Leave a Reply

Your email address will not be published. Required fields are marked *