java.lang.RuntimeException: 接收到 firebase 消息时无法创建服务错误
java.lang.RuntimeException: Unable to create service error when receiving a firebase messaging message
我正在设置 FirebaseMessaging
,当我收到消息时,我确实得到了我在 .onMessage
回调中设置的打印件:
I/flutter (27328): New FCM onMessage message : Instance of 'RemoteMessage'
I/flutter (27328):
I/flutter (27328): New FCM onMessage message id: 0:1653641357492638%dad60691dad60691
W/com.xxx.foods(27328): Accessing hidden method Landroid/os/WorkSource;->add(I)Z (unsupported,test-api, reflection, allowed)
I/flutter (27328): New FCM onMessage message sentTime: 2022-05-27 10:49:17.485
W/com.xxx.foods(27328): Accessing hidden method Landroid/os/WorkSource;->add(ILjava/lang/String;)Z (unsupported,test-api, reflection, allowed)
W/com.xxx.foods(27328): Accessing hidden method Landroid/os/WorkSource;->get(I)I (unsupported, reflection, allowed)
W/com.xxx.foods(27328): Accessing hidden method Landroid/os/WorkSource;->getName(I)Ljava/lang/String; (unsupported, reflection, allowed)
I/flutter (27328): New FCM onMessage message notification title: a
I/flutter (27328): New FCM onMessage message notification body: a
但随后应用程序崩溃并出现错误:
D/AndroidRuntime(27328): Shutting down VM E/AndroidRuntime(27328): FATAL EXCEPTION: main E/AndroidRuntime(27328): Process: com.xxx.foods, PID: 27328 E/AndroidRuntime(27328): java.lang.RuntimeException: Unable to create service com.example.xxx.java.MyFirebaseMessagingService: java.lang.ClassNotFoundException: Didn't find class "com.example.xxx.java.MyFirebaseMessagingService" on path: DexPathList[[zip file "/data/app/~~LYrL5kv915DhEfzUSgPwZg==/com.xxx.foods-dIN5_0rsX6Wo-G0jfKtL2Q==/base.apk"],nativeLibraryDirectories=[/data/app/~~LYrL5kv915DhEfzUSgPwZg==/com.xxx.foods-dIN5_0rsX6Wo-G0jfKtL2Q==/lib/arm64, /data/app/~~LYrL5kv915DhEfzUSgPwZg==/com.xxx.foods-dIN5_0rsX6Wo-G0jfKtL2Q==/base.apk!/lib/arm64-v8a, /system/lib64, /system_ext/lib64]] E/AndroidRuntime(27328): at android.app.ActivityThread.handleCreateService(ActivityThread.java:4619) E/AndroidRuntime(27328): at android.app.ActivityThread.access00(ActivityThread.java:265) E/AndroidRuntime(27328): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2122) E/AndroidRuntime(27328): at android.os.Handler.dispatchMessage(Handler.java:106) E/AndroidRuntime(27328): at android.os.Looper.loopOnce(Looper.java:210) E/AndroidRuntime(27328): at android.os.Looper.loop(Looper.java:299) E/AndroidRuntime(27328): at android.app.ActivityThread.main(ActivityThread.java:8166) E/AndroidRuntime(27328): at java.lang.reflect.Method.invoke(Native Method) E/AndroidRuntime(27328): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:556) E/AndroidRuntime(27328): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1037) E/AndroidRuntime(27328): Caused by: java.lang.ClassNotFoundException: Didn't find class "com.example.xxx.java.MyFirebaseMessagingService" on path: DexPathList[[zip file "/data/app/~~LYrL5kv915DhEfzUSgPwZg==/com.xxx.foods-dIN5_0rsX6Wo-G0jfKtL2Q==/base.apk"],nativeLibraryDirectories=[/data/app/~~LYrL5kv915DhEfzUSgPwZg==/com.xxx.foods-dIN5_0rsX6Wo-G0jfKtL2Q==/lib/arm64, /data/app/~~LYrL5kv915DhEfzUSgPwZg==/com.xxx.foods-dIN5_0rsX6Wo-G0jfKtL2Q==/base.apk!/lib/arm64-v8a, /system/lib64, /system_ext/lib64]] E/AndroidRuntime(27328): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:218) E/AndroidRuntime(27328): at java.lang.ClassLoader.loadClass(ClassLoader.java:379) E/AndroidRuntime(27328): at java.lang.ClassLoader.loadClass(ClassLoader.java:312) E/AndroidRuntime(27328): at android.app.AppComponentFactory.instantiateService(AppComponentFactory.java:129) E/AndroidRuntime(27328): at androidx.core.app.CoreComponentFactory.instantiateService(CoreComponentFactory.java:75) E/AndroidRuntime(27328): at android.app.ActivityThread.handleCreateService(ActivityThread.java:4588) E/AndroidRuntime(27328): ... 9 more D/OOMEventManagerFK(27328): checkEventAndDumpForJE: 0 I/Process (27328): Sending signal. PID: 27328 SIG: 9 Lost connection to device
在我的 android/app/main/AndroidManifest.xml 中,我设置了文档中描述的服务:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.xxx">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:name="io.flutter.app.FlutterApplication"
android:label="xxx"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<!-- Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this tutorial
screen fades out. A tutorial screen is useful to avoid any visual
gap between the end of Android's launch screen and the painting of
Flutter's first frame. -->
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<service
android:name=".java.MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
并在 MainActivity.kt
中我设置了 FlutterFragmentedActivity:
package com.example.xxx
//import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
import androidx.annotation.NonNull;
//class MainActivity: FlutterActivity() {
//}
class MainActivity: FlutterFragmentActivity() {
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
}
}
还有什么我应该设置的吗?
我是这样初始化的:
print('New FCM firebaseMessagingBackgroundHandler message : ${message.toString()} \n\n');
print('New FCM firebaseMessagingBackgroundHandler message id: ${message.messageId}');
print('New FCM firebaseMessagingBackgroundHandler message sentTime: ${message.sentTime}');
print('New FCM firebaseMessagingBackgroundHandler message notification title: ${message.notification.title}');
print('New FCM firebaseMessagingBackgroundHandler message notification body: ${message.notification.body}');
await Firebase.initializeApp();
}
void main() async {
// set the publishable key for Stripe - this is mandatory
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
...
但是,由于我需要在收到消息时发送 Bloc 事件,我在下一个屏幕中设置了 FirebaseMessaging,这将使 Bloc 在树中可用:
class _ShowSplashScreenWidgetState extends State<ShowSplashScreenWidget> {
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
String fcmToken;
@override
void initState() {
super.initState();
/// FCM setup
_firebaseMessaging.requestPermission(sound: true, badge: true, alert: true, provisional: false, carPlay: false, criticalAlert: false);
_firebaseMessaging.getToken().then((token) {
print(' _firebaseMessaging.getToken token: $token');
if (mounted) {
setState(() {
fcmToken = token;
});
} else {
fcmToken = token;
}
});
FirebaseMessaging.onMessage.listen((message) {
print('New FCM onMessage message : ${message.toString()} \n\n');
print('New FCM onMessage message id: ${message.messageId}');
print('New FCM onMessage message sentTime: ${message.sentTime}');
print('New FCM onMessage message notification title: ${message.notification.title}');
print('New FCM onMessage message notification body: ${message.notification.body}');
NotificationModel notification = NotificationModel(
id: message.messageId, read: false, date: message.sentTime, title: message.notification.title, body: message.notification.body);
// BlocProvider.of<NotificationBloc>(context).add(SaveNotification(notification: notification));
});
FirebaseMessaging.onMessageOpenedApp.listen((message) {
print('New FCM onMessageOpenedApp message : ${message.toString()} \n\n');
print('New FCM onMessageOpenedApp message id: ${message.messageId}');
print('New FCM onMessageOpenedApp message sentTime: ${message.sentTime}');
print('New FCM onMessageOpenedApp message notification title: ${message.notification.title}');
print('New FCM onMessageOpenedApp message notification body: ${message.notification.body}');
NotificationModel notification = NotificationModel(
id: message.messageId, read: false, date: message.sentTime, title: message.notification.title, body: message.notification.body);
BlocProvider.of<NotificationBloc>(context).add(SaveNotification(notification: notification));
});
....
你有 class java.MyFirebaseMessagingService
吗?
另外,在较新版本的 FCM 中,您不必在清单或代码中初始化服务 class,
很简单,从 AndroidManifest.xml
中删除 MyFirebaseMessagingService
服务标签
我正在设置 FirebaseMessaging
,当我收到消息时,我确实得到了我在 .onMessage
回调中设置的打印件:
I/flutter (27328): New FCM onMessage message : Instance of 'RemoteMessage'
I/flutter (27328):
I/flutter (27328): New FCM onMessage message id: 0:1653641357492638%dad60691dad60691
W/com.xxx.foods(27328): Accessing hidden method Landroid/os/WorkSource;->add(I)Z (unsupported,test-api, reflection, allowed)
I/flutter (27328): New FCM onMessage message sentTime: 2022-05-27 10:49:17.485
W/com.xxx.foods(27328): Accessing hidden method Landroid/os/WorkSource;->add(ILjava/lang/String;)Z (unsupported,test-api, reflection, allowed)
W/com.xxx.foods(27328): Accessing hidden method Landroid/os/WorkSource;->get(I)I (unsupported, reflection, allowed)
W/com.xxx.foods(27328): Accessing hidden method Landroid/os/WorkSource;->getName(I)Ljava/lang/String; (unsupported, reflection, allowed)
I/flutter (27328): New FCM onMessage message notification title: a
I/flutter (27328): New FCM onMessage message notification body: a
但随后应用程序崩溃并出现错误:
D/AndroidRuntime(27328): Shutting down VM E/AndroidRuntime(27328): FATAL EXCEPTION: main E/AndroidRuntime(27328): Process: com.xxx.foods, PID: 27328 E/AndroidRuntime(27328): java.lang.RuntimeException: Unable to create service com.example.xxx.java.MyFirebaseMessagingService: java.lang.ClassNotFoundException: Didn't find class "com.example.xxx.java.MyFirebaseMessagingService" on path: DexPathList[[zip file "/data/app/~~LYrL5kv915DhEfzUSgPwZg==/com.xxx.foods-dIN5_0rsX6Wo-G0jfKtL2Q==/base.apk"],nativeLibraryDirectories=[/data/app/~~LYrL5kv915DhEfzUSgPwZg==/com.xxx.foods-dIN5_0rsX6Wo-G0jfKtL2Q==/lib/arm64, /data/app/~~LYrL5kv915DhEfzUSgPwZg==/com.xxx.foods-dIN5_0rsX6Wo-G0jfKtL2Q==/base.apk!/lib/arm64-v8a, /system/lib64, /system_ext/lib64]] E/AndroidRuntime(27328): at android.app.ActivityThread.handleCreateService(ActivityThread.java:4619) E/AndroidRuntime(27328): at android.app.ActivityThread.access00(ActivityThread.java:265) E/AndroidRuntime(27328): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2122) E/AndroidRuntime(27328): at android.os.Handler.dispatchMessage(Handler.java:106) E/AndroidRuntime(27328): at android.os.Looper.loopOnce(Looper.java:210) E/AndroidRuntime(27328): at android.os.Looper.loop(Looper.java:299) E/AndroidRuntime(27328): at android.app.ActivityThread.main(ActivityThread.java:8166) E/AndroidRuntime(27328): at java.lang.reflect.Method.invoke(Native Method) E/AndroidRuntime(27328): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:556) E/AndroidRuntime(27328): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1037) E/AndroidRuntime(27328): Caused by: java.lang.ClassNotFoundException: Didn't find class "com.example.xxx.java.MyFirebaseMessagingService" on path: DexPathList[[zip file "/data/app/~~LYrL5kv915DhEfzUSgPwZg==/com.xxx.foods-dIN5_0rsX6Wo-G0jfKtL2Q==/base.apk"],nativeLibraryDirectories=[/data/app/~~LYrL5kv915DhEfzUSgPwZg==/com.xxx.foods-dIN5_0rsX6Wo-G0jfKtL2Q==/lib/arm64, /data/app/~~LYrL5kv915DhEfzUSgPwZg==/com.xxx.foods-dIN5_0rsX6Wo-G0jfKtL2Q==/base.apk!/lib/arm64-v8a, /system/lib64, /system_ext/lib64]] E/AndroidRuntime(27328): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:218) E/AndroidRuntime(27328): at java.lang.ClassLoader.loadClass(ClassLoader.java:379) E/AndroidRuntime(27328): at java.lang.ClassLoader.loadClass(ClassLoader.java:312) E/AndroidRuntime(27328): at android.app.AppComponentFactory.instantiateService(AppComponentFactory.java:129) E/AndroidRuntime(27328): at androidx.core.app.CoreComponentFactory.instantiateService(CoreComponentFactory.java:75) E/AndroidRuntime(27328): at android.app.ActivityThread.handleCreateService(ActivityThread.java:4588) E/AndroidRuntime(27328): ... 9 more D/OOMEventManagerFK(27328): checkEventAndDumpForJE: 0 I/Process (27328): Sending signal. PID: 27328 SIG: 9 Lost connection to device
在我的 android/app/main/AndroidManifest.xml 中,我设置了文档中描述的服务:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.xxx">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:name="io.flutter.app.FlutterApplication"
android:label="xxx"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<!-- Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this tutorial
screen fades out. A tutorial screen is useful to avoid any visual
gap between the end of Android's launch screen and the painting of
Flutter's first frame. -->
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<service
android:name=".java.MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
并在 MainActivity.kt
中我设置了 FlutterFragmentedActivity:
package com.example.xxx
//import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant
import androidx.annotation.NonNull;
//class MainActivity: FlutterActivity() {
//}
class MainActivity: FlutterFragmentActivity() {
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
}
}
还有什么我应该设置的吗?
我是这样初始化的:
print('New FCM firebaseMessagingBackgroundHandler message : ${message.toString()} \n\n');
print('New FCM firebaseMessagingBackgroundHandler message id: ${message.messageId}');
print('New FCM firebaseMessagingBackgroundHandler message sentTime: ${message.sentTime}');
print('New FCM firebaseMessagingBackgroundHandler message notification title: ${message.notification.title}');
print('New FCM firebaseMessagingBackgroundHandler message notification body: ${message.notification.body}');
await Firebase.initializeApp();
}
void main() async {
// set the publishable key for Stripe - this is mandatory
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
...
但是,由于我需要在收到消息时发送 Bloc 事件,我在下一个屏幕中设置了 FirebaseMessaging,这将使 Bloc 在树中可用:
class _ShowSplashScreenWidgetState extends State<ShowSplashScreenWidget> {
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
String fcmToken;
@override
void initState() {
super.initState();
/// FCM setup
_firebaseMessaging.requestPermission(sound: true, badge: true, alert: true, provisional: false, carPlay: false, criticalAlert: false);
_firebaseMessaging.getToken().then((token) {
print(' _firebaseMessaging.getToken token: $token');
if (mounted) {
setState(() {
fcmToken = token;
});
} else {
fcmToken = token;
}
});
FirebaseMessaging.onMessage.listen((message) {
print('New FCM onMessage message : ${message.toString()} \n\n');
print('New FCM onMessage message id: ${message.messageId}');
print('New FCM onMessage message sentTime: ${message.sentTime}');
print('New FCM onMessage message notification title: ${message.notification.title}');
print('New FCM onMessage message notification body: ${message.notification.body}');
NotificationModel notification = NotificationModel(
id: message.messageId, read: false, date: message.sentTime, title: message.notification.title, body: message.notification.body);
// BlocProvider.of<NotificationBloc>(context).add(SaveNotification(notification: notification));
});
FirebaseMessaging.onMessageOpenedApp.listen((message) {
print('New FCM onMessageOpenedApp message : ${message.toString()} \n\n');
print('New FCM onMessageOpenedApp message id: ${message.messageId}');
print('New FCM onMessageOpenedApp message sentTime: ${message.sentTime}');
print('New FCM onMessageOpenedApp message notification title: ${message.notification.title}');
print('New FCM onMessageOpenedApp message notification body: ${message.notification.body}');
NotificationModel notification = NotificationModel(
id: message.messageId, read: false, date: message.sentTime, title: message.notification.title, body: message.notification.body);
BlocProvider.of<NotificationBloc>(context).add(SaveNotification(notification: notification));
});
....
你有 class java.MyFirebaseMessagingService
吗?
另外,在较新版本的 FCM 中,您不必在清单或代码中初始化服务 class,
很简单,从 AndroidManifest.xml
MyFirebaseMessagingService
服务标签