You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Qt Android应用中QtService与FirebaseMessagingService整合问题咨询

解决Qt Android + Firebase Messaging的单继承冲突问题

我之前在做Qt Android应用集成Firebase云消息的时候,也碰到过这个一模一样的问题——Java单继承确实卡死了我们的路,但其实用代理/分离职责的思路就能搞定,不需要纠结多继承,给你分享我亲测有效的方案:

核心思路

既然不能让一个类同时继承QtService和FirebaseMessagingService,那我们就把这两个职责拆成两个独立的类:

  • 一个专门负责Firebase消息接收:继承FirebaseMessagingService,处理推送消息、Token更新等逻辑
  • 一个专门负责Qt后台服务:继承QtService,处理Qt层面的后台任务、JNI交互等
    然后通过JNI桥接让两个类协同工作,把Firebase的消息传递到Qt C++层。

具体实现步骤

1. 实现Firebase消息接收类

创建一个继承FirebaseMessagingService的Java类,重写核心方法处理消息:

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import org.qtproject.qt5.android.QtNative;

public class MyFirebaseMessagingService extends FirebaseMessagingService {
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        // 解析Firebase推送的消息内容
        String title = remoteMessage.getNotification().getTitle();
        String body = remoteMessage.getNotification().getBody();
        // 自定义数据可通过remoteMessage.getData()获取

        // 通过JNI把消息传递到Qt C++层
        QtNative.invokeMethod("notifyFromFirebase", new Object[]{title, body});
    }

    @Override
    public void onNewToken(String token) {
        // 把新的Token传给Qt层
        QtNative.invokeMethod("updateFirebaseToken", new Object[]{token});
    }
}

2. 实现Qt后台服务类

创建继承QtService的类,负责Qt的后台运行逻辑(如果你的应用需要后台持续服务的话):

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

public class MyQtService extends QtService {
    @Override
    public void onCreate() {
        super.onCreate();
        // 初始化Qt相关后台逻辑,比如启动Qt线程
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // 处理服务启动命令,比如响应Firebase消息触发的逻辑
        return super.onStartCommand(intent, flags, startId);
    }
}

3. 配置AndroidManifest.xml

两个服务都需要在Manifest里注册,同时配置Firebase相关组件:

<!-- Firebase消息服务 -->
<service
    android:name=".MyFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

<!-- Qt后台服务 -->
<service
    android:name=".MyQtService"
    android:process=":qt_service"
    android:permission="android.permission.BIND_JOB_SERVICE">
    <meta-data
        android:name="android.app.lib_name"
        android:value="你的Qt应用库名" />
</service>

<!-- Firebase核心配置 -->
<meta-data
    android:name="com.google.firebase.messaging.default_notification_channel_id"
    android:value="@string/default_notification_channel_id" />

4. 在Qt C++层接收消息

在Qt的C++代码里,注册对应的JNI方法,接收来自Firebase的消息:

#include <QAndroidJniObject>
#include <QAndroidJniEnvironment>
#include <QDebug>

// 接收Firebase推送消息的JNI方法
static void notifyFromFirebase(JNIEnv *env, jobject /*obj*/, jstring title, jstring body)
{
    QString qTitle = QAndroidJniObject(title).toString();
    QString qBody = QAndroidJniObject(body).toString();
    // 在这里处理推送消息,比如弹出本地通知、更新UI等
    qDebug() << "收到Firebase推送:" << qTitle << qBody;
}

// 接收Firebase Token更新的JNI方法
static void updateFirebaseToken(JNIEnv *env, jobject /*obj*/, jstring token)
{
    QString qToken = QAndroidJniObject(token).toString();
    // 保存新Token到本地或上传至服务器
    qDebug() << "Firebase Token更新:" << qToken;
}

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    // 注册JNI方法
    JNINativeMethod methods[] = {
        {"notifyFromFirebase", "(Ljava/lang/String;Ljava/lang/String;)V", (void*)notifyFromFirebase},
        {"updateFirebaseToken", "(Ljava/lang/String;)V", (void*)updateFirebaseToken}
    };
    QAndroidJniObject javaClass("org/qtproject/qt5/android/QtNative");
    QAndroidJniEnvironment env;
    jclass objectClass = env->GetObjectClass(javaClass.object<jobject>());
    env->RegisterNatives(objectClass, methods, sizeof(methods)/sizeof(methods[0]));
    env->DeleteLocalRef(objectClass);

    // 其他应用初始化逻辑...

    return app.exec();
}

额外注意点

  • 如果你的应用不需要独立的Qt后台服务,其实可以不用创建MyQtService——直接在MyFirebaseMessagingService里通过JNI调用Qt逻辑就行,Qt应用在后台时也能接收Firebase消息(只要系统没杀死进程)
  • 针对Android 8.0+的后台限制,如果需要在应用进程被杀死后仍能接收推送,要确保Firebase的消息是数据消息(而非纯通知消息),这样onMessageReceived会被触发,进而可以启动前台服务唤醒Qt进程
  • 测试时记得在Firebase控制台配置好Android应用的SHA-1和包名,确保推送能正常到达

内容的提问来源于stack exchange,提问作者Nick6707

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:39:47