Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Run on Android thread



  • Hi,

    I'm following this guide to implement some Android specific features in my application. The guide says that SOME Android APIs that MUST be called from Android UI thread. But how do I recognize which APIs are those? And what will happen if I call an API from Qt thread instead of Android UI thread?



  • @vlada said in Run on Android thread:

    what will happen if I call an API from Qt thread instead of Android UI thread?

    the human race will disappear from Earth...

    Seriuously, have you checked this part:

    To do such a call, from C/C++ Qt thread to Java Android UI thread, we need to do 3 steps:

    1. call a Java method from C/C++ Qt thread. The Java method will be executed in Qt thread, so we we need a way to access Android APIs in Android UI thread.

    2. our Java method uses Activity.runOnUiThread to post a runnable on Android UI thread. This runnable will be executed by the Android event loop on Android UI thread.

    3. the runnable accesses the Android APIs from Android UI thread.

    It looks like you're looking for runOnUIThread()



  • Basically, Android has the same principle as Qt. If an API has something to do with UI, it has to be run in the UI thread.

    What happens if you don't? You get a bug, hopefully a deterministic crash every time you execute that code; in the worst case a problem every now and then on devices that you haven't tested on.

    (I have not found any documentation about what APIs must be run in the UI thread, so it is just about following the general principle, moving execution to the UI thread and testing.)



  • @Pablo-J-Rogina Yes, I know how to implement it. It is in the guide. I'm just wondering when I have to use this approach and when not.

    @mvuori Thank you. In Qt it is quite clear for me what is UI and what not. If my application isn't in foreground, I don't touch the QML part. In Android it isn't that clear.

    If you check the guide, it describes how to set SD card (un)mount listener. I would say this has nothing to do with the UI.

    I'm wondering if my approach to show foreground service is correct or not. Currently I use this method to show it:

    public class MuzikaServiceOld extends QtService
        {
            private Handler handler;
    
            @Override
            public void onCreate() {
            super.onCreate();
            handler = new Handler();
            }
    
            public void showNotification(String text) {
            runOnUiThread(new MyNotification(this, text));
            }
    
            private void runOnUiThread(Runnable runnable) {
            handler.post(runnable);
            }
    }
    

    The class MyNotification in the run() method creates and shows the notification. The question is, if this is a correct solution, because I create a new instance of the notification each time I change it.

    The second possibility is this:

    public class MuzikaServiceOld extends QtService
        {
        NotificationManager mNotificationManager;
    
            @Override
            public void onCreate() {
            super.onCreate();
            mNotificationManager = new MyNotification(this);
            }
    
            public void showNotification(String text) {
            mNotificationManager.update(text);
            }
    }
    

    This works too but in this case I'm not showing and updating the notification from Android UI thread. But I don't create a new instance on every change.

    So the question is, which of these two solutions is better and which can lead to some problems. I hope this example explains better my question.


Log in to reply