运行应用程序后,QtService会在Android上自动重启

时间:2018-02-24 14:10:21

标签: android qt android-service

我能够在此link中找到使用Qt为Android创建服务的代码。我把服务代码放在单独的.so文件中,就像本文中的代码一样。但我有一个问题:

启动我的应用程序后,服务自动重启(Running services菜单中的0个进程和1个服务),如此图像(MyActivities)。

MyActivities (0 processes and 1 service)

我的manifest.xml(仅限相关行):

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

我的服务(java部分):

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:

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

此后,该服务不再有效!

此图片中的

My App是我在Android Studio中编码的服务,它运行良好。但Qt的服务有问题。

2 个答案:

答案 0 :(得分:2)

我遇到了与Qt 5.10.0相同的问题,正如您所遇到的那样,该服务从未超过onCreate()并很快被ANR杀死。 ANR堆栈跟踪显示如下:

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)

表明该服务等待信号量。进一步跟踪显示此等待发生在QtAndroidPrivate::waitForServiceSetup();androidjnimain.cpp的第548行QtAndroidPrivate::g_waitForServiceSetupSemaphore调用期间,等待QtAndroidPrivate::setOnBindListener(QtAndroidPrivate::OnBindListener *listener)被释放。这通常应发生在由QAndroidServicePrivate::QAndroidServicePrivate(QAndroidService *service)构造函数调用的QAndroidService (extends QCoreApplication)内,QCoreApplicationQAndroidService的私有成员,并与其一起创建。这意味着,如果您本机启动服务,则绝对不应使用QAndroidService,而应使用QtAndroidPrivate::setOnBindListener(this);,否则您的服务会卡在此信号量并获得ANR。

但是,即使我使用QTimer::singleShot(0,this, [this]{ QtAndroidPrivate::setOnBindListener(this);});,问题仍然存在于Qt 5.10.0中。在Qt 5.10.1中,我意识到调用main.cpp已被#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; } } 替换,让调用在构造函数返回后发生。这似乎暂时有效地解决了我的ANR问题;作为参考,我的only minor changes看起来像这样:

QAndroidService

奇怪的是,http://code.qt.io/cgit/qt/qtandroidextras.git/tree/dist/changes-5.10.1/?h=v5.10.1列出QCoreApplication,这是不正确的,因为它们显然修复了先前使Android服务无法使用的ANR问题。

所以解决方案似乎是使用Qt 5.10.1和public class ConfigSettings : IConfig { public string Connstring { get; } public string Context { get; set; } public ConfigSettings() { this.Context = ConfigurationManager.AppSettings["Context"]; this.Connstring = ConfigurationManager.ConnectionStrings[ConfigurationManager.AppSettings["Context"]] .ConnectionString; } } 而不是private readonly Factory factory = new Factory(new ConfigSettings());

答案 1 :(得分:0)

Ayberk整理了我。

我已经尝试使用Qt 5.12运行android服务4天了。 值得一提:

在清单中。您必须将android:enabled =“ true”作为服务标签的一部分,例如:

<service android:process=":qt" android:enabled="true" android:name="org.qtproject.example.MyCustomAppService">

Ayberks代码是我看到的唯一示例。在那之前什么都没做。

另外,如果在运行qAndroidservice.exec()之前运行无限循环,则android将终止该进程,并且您的输出很可能不会进入logcat。

[x]不起作用:

qInfo() << "You should see this once for app and once for service";
if (strcmp(argv[1], "-service") == 0) {
    qInfo() << "Service is running";
    QAndroidService svc(argc, argv);
    while (true) {
        qInfo("This may or may not get displayed");
    }
    qInfo() << "This output does not display";
    return svc.exec();
}

[+]起作用:

qInfo() << "You should see this once for app and once for service";
if (strcmp(argv[1], "-service") == 0) {
    qInfo() << "Service is running";
    QAndroidService svc(argc, argv);
    qInfo() << "You should see this";
    return svc.exec();
}

这似乎很明显,但是我试图在循环中延迟地重复gps上传。这似乎很容易。我认为更好的方法是使用QTimer。由于QAndroidService实际上可以运行,并且QWebSocket可以完美地工作。

第二:

qInfo和qDebug会在logcat中显示。只是不在QT Creators logcat中。我使用了Android Studio的logcat查看器,可以看到该服务的输出。

第三次。

我不知道将Java服务文件放在哪里。事实证明这不是很重要,或者我只是偶然将其放在正确的位置。我把它放进去 /QtProjFolder/Android/src/org/qtproject/example/MyCustomAppService.java,效果很好。

如果有人对与主应用程序通信有任何“好的”想法,请告诉我:)

我希望这可以帮助你们避免像我一样浪费4天。