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
相关产品推荐
相关产品推荐

