The future of Qt on Android looks bright
Urbi et Orbi
A new year just started a few weeks ago, but Qt on Android doesn’t have time to rest :).
The secret meeting
At the beginning of the year I attended a very important workshop in Oslo. For two full days KDAB (me) and Digia (Oslo office folks) secretly discussed the future of Qt on Android. We talked about lots of features that we are planning to implement in Qt 5.3, 5.4 and even in 5.5 and beyond. Well, today I want to share with you some of the secret :)!
In this article I’m going to highlight only one of them.
The prom queen
“Support for multiple surfaces and mixing raster/GL content” was by far the hottest topic, because lots of other features depend on it. It was also my top priority feature on my TODO list for Android.
What is wrong with current implementation? Well current implementation supports only a single android native surface, which can be used either by raster only apps with multiple top level widgets (e.g. the drop down list of a combobox is a top level widget) or by OpenGL apps, but is limited to a single top level widget (the OpenGL one). This limitation is very annoying because it makes QGLWidgets apps unusable on Android. It also makes it impossible for Qt to use the android native media video player, which is (seems to be?) required to play DRM videos.
A small step for Qt a giant leap for Qt on Android
Folks, I have good news on this matter! Even though the holiday period is over, KDAB started this year with a great gift for all Qt on Android devs out there! A few days ago I managed to have a single Android platform plugin which can be used by apps that mix QGLWidgets with QWidgets. The mandatory screenshot:
To accomplish this task I had to find a way to create multiple native android surfaces. On most (all?) the platforms supported by Qt it is a pretty easy job to have multiple native windows, but on Android it is a real pain in the … you know where :). More about this topic on the “behind the scenes” part.
Why didn’t I do it until now? Why did it take me so long to do it? Well, I had this feature in my mind for a very, very long time, but sadly I didn’t have enough time to check if it really works. KDAB gave me the needed time to do it 🙂 !
Behind the scenes
This is the boring technical part, if you really don’t care how it works, you can jump to the limitations chapter, but for a better understanding of the limitations I do recommend you spend a few more moments and read this part.
Why do we need multiple native android surfaces? For a better understanding let’s take a simple example: an application that needs a GL surface and also has some (old fashioned) QWidget-based controls. For this application Qt needs two surfaces, one for the GLWidget and one from the QWidget.
Why is it so hard to create another native android surface? Well, there is no problem to create one more native android surface, the problem comes when you need to control its Z order. The Z order is very important. Let’s assume that you need to show a dialog on top of a GLWigdet, but you can’t guarantee that the new surface will be created on top of the GLWigdet surface. It is possible it will be created behind the GLWigdet surface so the user will not be able to see the new dialog.
setZOrderMediaOverlay saved the day! This method does all the magic, it allows us to control whether the new surface is placed on top of another regular surface. We still can’t control the Z order of two surfaces that have the same ZOrderMediaOverlay flag! It just helps us to create one more drawing layer.
How does it work for Qt? Now Qt uses three different layers:
- the topmost layer contains a custom AbsoluteLayout view which is used by Qt to create a dummy (fully transparent) control every time you want to edit something. The dummy control is needed by Android window manager to pan/resize your application window when the software keyboard appears. The custom AbsoluteLayout view will be used in the future to add native controls (e.g. WebView).
- the middle layer, is used by Qt to create a single SurfaceView with ZOrderMediaOverlay flag set to true! This surface is used by Qt to draw all raster windows. Yes, one surface is enough for all QWidget based top level widgets. Maybe in the future we can use it to push a single Qt GL Window that will be on top of another GL Windows.
- the bottommost layer is used by Qt to create SurfaceView(s) which are used for GL windows and by native android media video player.
Limitations
As I said previously, ZOrderMediaOverlay only helped us to create a new layer (the middle one) but we still have the Z order problem for the surfaces created on the same layer.
- the last layer surfaces can’t overlap (e.g. you can’t overlap correctly multiple GL Windows).
- because the native controls will be placed on the topmost layer, Qt can’t put anything over them.
- only basic transformations can be applied to native controls (position and size).
Other changes done to android platform plugin
Besides the work on creating multiple native surfaces, I did the necessary changes to have a single android platform plugin and reworked the raster and opengl code (got rid of eglfs and fbconvenience dependencies :)).
The progress sounds great! I personally would very much like to start using Qt on Android but what is the process of actually developing and shipping an application from A to Z? I am interested in both open source and commercial options.
Check:
http://www.kdab.com/qt-on-android-episode-2/
http://www.kdab.com/qt-android-episode-3/
Great news! You mentioned WebView on the top most layer. Will WebView elements be available as QML elements? Is it already possible to add a fullscreen WebView to the top most layer?
First let me clarify one important thing. This change only lays the groundwork for integrating native controls. But native controls will not be part of Qt 5.3!
Yes AFAIK WebView native control will be available as a QML element.
How could I putting ads in my app?
You need to extend the Java part.
I’ll write an article about extending your application.
Waiting for that… Please do. it.
Thank you.
may you show us how to put ads in the apps developed by Qt on android?Like tapjoy and admob.
Well, the article will focus on something else, but it will contain all the information you need to do it yourself.
Thanks, this is not a trivial task for me, it would take me a lot of times to figure it out all by myself(can’t find the answer by google).
Could you share some example project of that?
Very good news!
I managed to ad admob to qt2 android application by adding adView to QtLaout which i get in class inherited from QtActivity.
http://xanm.blogspot.ru/2014/03/admob-in-qt.html
Could you give me some advices for better way to do this?
And may be even develop qml plugin for this task?
How about adding some support also for non-UI applications (background processes)?
Check my previous reply 🙂 !
Not sure which reply you are referring to. I know it can be done manually. But it could be better supported – for example things like localisation & launching external url work only on a UI application out of the box right now.
I don’t think you need an UI to use Qt Positioning module or QDesktopServices class.
To create a service you need to do a few things manually (e.g. declare the service in the manifest file, etc. ).
Great work, is already on the qt 5.3 git source code?, i was unable to make mediaplayer to work on android, i believe its related to this…
Yes it is! As I said in the article, this change will enable in *the future* this features! QWidget based mediaplayer is not scheduled for 5.3.
Good work. In the past days you’ve stated above about how to do admob in application.I’ve been waiting a long time for you in this . I hope the good news about it from you.
Good news, where could I find the article?Thanks
I think this is among the most significant info for me.
And i am glad reading your article. But wanna remark on few general things, The web site style is
perfect, the articles is really nice : D. Good
job, cheers
hi, I’m a stranger on Qt. And how can I build Qt webkit on Android, as fo need, we don’t want to use Qt webEngine, thanks
You clone qtwebkit and build it. But I need to warn you that QtWebKit size is huge …
What is the status of being able to combine QGLWidgets and QWidgets in a single Android application? It doesn’t look like it’s in Qt 5.4 based on the platform notes. Is it going to be in a future version?
Sadly my patch (https://codereview.qt-project.org/#/c/92070) which fixes some problems with QGLWidget is on hold. Fortunately you can use the new class QOpenGLWidget (http://doc.qt.io/qt-5/qopenglwidget.html) which should work just fine in combination with QWidgets. But I do recommend you consider move away from QWidgets and switch to QML.
Thanks for the info, we’ll look into it.