Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QtService automatically restarts on Android after running the application

I was able to find a code that creates a service for Android using Qt in this link. I put the service code in separate .so files like the code in this article. But I have a problem:

After I started my application, the service auto restarted (0 processes and 1 service in Running services menu) like in this image (MyActivities).

MyActivities (0 processes and 1 service)

My manifest.xml (only relevant lines):

<service android:process=":qt" android:name="org.qtproject.example.MyService">
    <!-- android:process=":qt" is needed to force the service to run on a separate process than the Activity -->

    <!-- Application arguments -->
    <meta-data android:name="android.app.arguments" android:value="-service"/>
    <!-- Application arguments -->

    <!-- If you are using the same application (.so file) for activity and also for service, then you
         need to use *android.app.arguments* to pass some arguments to your service in order to know which
         one is which.
    -->

    <!-- Application to launch -->
    <meta-data android:name="android.app.lib_name" android:value="MyService"/>
    <!-- Application to launch -->

    <!-- Ministro -->
    <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
    <meta-data android:name="android.app.repository" android:value="default"/>
    <meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
    <meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
    <!-- Ministro -->

    <!-- Deploy Qt libs as part of package -->
    <meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
    <meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
    <meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
    <!-- Deploy Qt libs as part of package -->

    <!-- Run with local libs -->
    <meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
    <meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
    <meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
    <meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
    <meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
    <!-- Run with local libs -->

    <!--  Messages maps -->
    <meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
    <meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
    <meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
    <!--  Messages maps -->

    <!-- Background running -->
    <meta-data android:name="android.app.background_running" android:value="true"/>
    <!-- Background running -->
</service>

My service (java part):

package org.qtproject.example;

import android.content.Context;
import android.content.Intent;
import org.qtproject.qt5.android.bindings.QtService;

public class MyService extends QtService {
    public static void startMyService(Context context) {
        Intent intent = new Intent(context, MyService.class);   // New Intent;
        context.startService(intent);                           // Start service;
    }
}

Logcat when the service restart:

E/ActivityManager( 1553): ANR in org.qtproject.example:qt
E/ActivityManager( 1553): PID: 3006
E/ActivityManager( 1553): Reason: Executing service org.qtproject.example/.MyService
E/ActivityManager( 1553): Load: 0.59 / 0.56 / 0.24
E/ActivityManager( 1553): CPU usage from 17710ms to 0ms ago:
E/ActivityManager( 1553):   2.3% 1553/system_server: 0.9% user + 1.3% kernel / faults: 2515 minor 1 major
E/ActivityManager( 1553):   1.5% 1146/surfaceflinger: 0% user + 1.4% kernel / faults: 2 minor
E/ActivityManager( 1553):   1.4% 1668/com.android.systemui: 0.5% user + 0.9% kernel / faults: 2944 minor
E/ActivityManager( 1553):   0.3% 1150/adbd: 0% user + 0.3% kernel / faults: 176 minor
E/ActivityManager( 1553):   0.2% 2194/com.google.android.gms: 0.2% user + 0% kernel / faults: 2607 minor
E/ActivityManager( 1553):   0.1% 2761/com.android.settings: 0.1% user + 0% kernel / faults: 1130 minor
E/ActivityManager( 1553):   0.1% 1141/logd: 0% user + 0% kernel / faults: 1 minor
E/ActivityManager( 1553):   0% 1155/mediaserver: 0% user + 0% kernel / faults: 4 minor
E/ActivityManager( 1553):   0% 1724/com.google.android.gms.persistent: 0% user + 0% kernel / faults: 8 minor
E/ActivityManager( 1553):   0% 1776/com.android.phone: 0% user + 0% kernel / faults: 2 minor
E/ActivityManager( 1553):   0% 1797/com.android.launcher: 0% user + 0% kernel / faults: 607 minor
E/ActivityManager( 1553):   0% 2030/com.google.process.gapps: 0% user + 0% kernel / faults: 344 minor
E/ActivityManager( 1553):  +0% 3027/logcat: 0% user + 0% kernel
E/ActivityManager( 1553): 3.2% TOTAL: 1.1% user + 1.7% kernel + 0.1% iowait + 0.1% softirq
E/ActivityManager( 1553): CPU usage from 1336ms to 1838ms later:
E/ActivityManager( 1553):   16% 1553/system_server: 4% user + 12% kernel / faults: 15 minor
E/ActivityManager( 1553):     14% 1792/Binder_4: 2% user + 12% kernel
E/ActivityManager( 1553):   1.8% 1146/surfaceflinger: 0% user + 1.8% kernel
E/ActivityManager( 1553):     1.8% 1200/Binder_1: 0% user + 1.8% kernel
E/ActivityManager( 1553):   1.8% 2761/com.android.settings: 1.8% user + 0% kernel / faults: 8 minor
E/ActivityManager( 1553):     1.8% 2761/ndroid.settings: 0% user + 1.8% kernel
E/ActivityManager( 1553): 9.1% TOTAL: 1% user + 6.1% kernel + 2% iowait
I/ActivityManager( 1553): Killing 3006:org.qtproject.example:qt/u0a58 (adj 0): bg anr
W/libprocessgroup( 1553): failed to open /acct/uid_10058/pid_3006/cgroup.procs: No such file or directory
W/libprocessgroup( 1553): failed to open /acct/uid_10058/pid_3006/cgroup.procs: No such file or directory
W/ActivityManager( 1553): Scheduling restart of crashed service org.qtproject.example/.MyService in 43754ms
D/EGL_emulation( 1668): eglMakeCurrent: 0xb312e100: ver 2 0
W/ResourceType( 2761): No package identifier when getting value for resource number 0x00000000
W/PackageManager( 2761): Failure retrieving resources for org.qtproject.example: Resource ID #0x0
W/ResourceType( 2761): No package identifier when getting value for resource number 0x00000000
W/PackageManager( 2761): Failure retrieving resources for com.google.android.gsf.login: Resource ID #0x0
W/ResourceType( 2761): No package identifier when getting value for resource number 0x00000000
W/PackageManager( 2761): Failure retrieving resources for org.qtproject.example: Resource ID #0x0
W/ResourceType( 2761): No package identifier when getting value for resource number 0x00000000
W/PackageManager( 2761): Failure retrieving resources for com.google.android.gsf.login: Resource ID #0x0
W/ResourceType( 2761): No package identifier when getting value for resource number 0x00000000
W/PackageManager( 2761): Failure retrieving resources for org.qtproject.example: Resource ID #0x0
W/ResourceType( 2761): No package identifier when getting value for resource number 0x00000000
W/PackageManager( 2761): Failure retrieving resources for com.google.android.gsf.login: Resource ID #0x0
W/ResourceType( 2761): No package identifier when getting value for resource number 0x00000000
W/PackageManager( 2761): Failure retrieving resources for org.qtproject.example: Resource ID #0x0
W/ResourceType( 2761): No package identifier when getting value for resource number 0x00000000
W/PackageManager( 2761): Failure retrieving resources for com.google.android.gsf.login: Resource ID #0x0
W/ResourceType( 2761): No package identifier when getting value for resource number 0x00000000
W/PackageManager( 2761): Failure retrieving resources for org.qtproject.example: Resource ID #0x0
W/ResourceType( 2761): No package identifier when getting value for resource number 0x00000000
W/PackageManager( 2761): Failure retrieving resources for com.google.android.gsf.login: Resource ID #0x0
W/ResourceType( 2761): No package identifier when getting value for resource number 0x00000000
W/PackageManager( 2761): Failure retrieving resources for org.qtproject.example: Resource ID #0x0
W/ResourceType( 2761): No package identifier when getting value for resource number 0x00000000
W/PackageManager( 2761): Failure retrieving resources for com.google.android.gsf.login: Resource ID #0x0

After this, the service is no longer active!

My App in this picture is a service I code in Android Studio and it works perfectly. But service in Qt have problem.

like image 232
tulm Avatar asked Dec 07 '25 17:12

tulm


1 Answers

I had the same problem with Qt 5.10.0 and as you are experiencing, the service never got past onCreate() and was shortly killed by an ANR. The ANR stack trace showed the following:

native: #00 pc 000174e8 /system/lib/libc.so (syscall+28)
native: #01 pc 0004777d /system/lib/libc.so (_ZL24__pthread_cond_timedwaitP23pthread_cond_internal_tP15pthread_mutex_tbPK8timespec+102)
native: #02 pc 0007888f /data/app/com.ourcompany.ourapp-1/lib/arm/libQt5Core.so (???)
native: #03 pc 0007873d /data/app/com.ourcompany.ourapp-1/lib/arm/libQt5Core.so (_ZN14QWaitCondition4waitEP6QMutexm+100)
native: #04 pc 000756cd /data/app/com.ourcompany.ourapp-1/lib/arm/libQt5Core.so (_ZN10QSemaphore7acquireEi+46)
native: #05 pc 00019975 /data/data/com.ourcompany.ourapp/qt-reserved-files/plugins/platforms/android/libqtforandroid.so (???)
at org.qtproject.qt5.android.QtNative.startQtApplication(Native method)
at org.qtproject.qt5.android.QtNative.startApplication(QtNative.java:333)
at org.qtproject.qt5.android.QtServiceDelegate.startApplication(QtServiceDelegate.java:176)
at java.lang.reflect.Method.invoke!(Native method)
at org.qtproject.qt5.android.bindings.QtLoader.loadApplication(QtLoader.java:251)
at org.qtproject.qt5.android.bindings.QtLoader.startApp(QtLoader.java:676)
at org.qtproject.qt5.android.bindings.QtServiceLoader.onCreate(QtServiceLoader.java:60)
at org.qtproject.qt5.android.bindings.QtService.onCreateHook(QtService.java:54)
at org.qtproject.qt5.android.bindings.QtService.onCreate(QtService.java:60)
at com.ourcompany.ourapp.OurService.onCreate(OurService.java:26)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3231)
at android.app.ActivityThread.-wrap5(ActivityThread.java:-1)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1597)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6236)
at java.lang.reflect.Method.invoke!(Native method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:891)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:781)

which showed that the service was stuck waiting on a semaphore. Tracing this further reveals that this waiting occurs during the QtAndroidPrivate::waitForServiceSetup(); call at line 548 in androidjnimain.cpp, waiting on QtAndroidPrivate::g_waitForServiceSetupSemaphore to be released. This should normally occur within QtAndroidPrivate::setOnBindListener(QtAndroidPrivate::OnBindListener *listener) that is called by the QAndroidServicePrivate::QAndroidServicePrivate(QAndroidService *service) constructor, that is a private member of QAndroidService (extends QCoreApplication) and is created alongside it. This means that you should absolutely not use QCoreApplication but QAndroidService if you're launching your service natively, otherwise your service gets stuck at this semaphore and gets an ANR.

However, even if I used QAndroidService, the ANR problem persisted in Qt 5.10.0. In Qt 5.10.1, I realized that the call QtAndroidPrivate::setOnBindListener(this); was replaced with QTimer::singleShot(0,this, [this]{ QtAndroidPrivate::setOnBindListener(this);}); letting the call occur after the constructor returns. This seems to have effectively fixed the ANR problem for me for the moment; for reference, my main.cpp looks like this:

#include <QAndroidService>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <string.h>

int main(int argc, char** argv){

    //GUI
    if(argc <= 1){
        QGuiApplication app(argc, argv);
        qInfo() << "Service GUI starting...";
        QQmlApplicationEngine engine;
        engine.load(QUrl(QStringLiteral("qrc:///src/main.qml")));
        return app.exec();
    }

    //Service
    else if(argc > 1 && strcmp(argv[1], "-service") == 0){
        QAndroidService app(argc, argv);
        qInfo() << "Service starting...";

        // My service stuff

        return app.exec();
    }

    //Unrecognized argument
    else{
        qWarning() << "Unrecognized command line argument.";
        return -1;
    }
}

What is weird is that http://code.qt.io/cgit/qt/qtandroidextras.git/tree/dist/changes-5.10.1/?h=v5.10.1 lists only minor changes, which is not true since they apparently fixed the ANR problem that previously made Android services effectively unusable.

So the solution seems to be using Qt 5.10.1 with QAndroidService instead of QCoreApplication.

like image 118
Ayberk Özgür Avatar answered Dec 10 '25 22:12

Ayberk Özgür