java.lang.RuntimeException: 在接收Firebase消息时创建服务出错

3

我正在设置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.access$1800(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));
    });

....


1个回答

8
你是否有类java.MyFirebaseMessagingService? 此外,在较新版本的FCM中,您无需在清单或代码中初始化服务类, 只需简单地从AndroidManifest.xml中删除MyFirebaseMessagingService服务标记即可。

1
嗨,感谢您的回答。确实我没有它...那就是问题所在,谢谢!我太蠢了,竟然从Android指南中复制了清单片段...我想现在是喝咖啡的时候了...再次感谢。干杯! - Vincenzo
非常欢迎,Salut :) - Abdallah A. Odeh
3
你能详细说明一下这个解决方案吗?我也是从文档中复制了代码片段并将其粘贴到了我的AndroidManifest.xml文件中,这样做不正确吗? - Calholl
请问您能详细说明这一步骤吗?文档是否已过时? - Ritik Jangir
2
@Calholl 是的,我正在使用Flutter。我使用了相同的代码,但每当我收到任何通知时,我的应用程序就会崩溃。 - undefined
1
@Calholl 是的,我在使用Flutter,我使用相同的代码,每当我收到任何通知时,我的应用程序就会崩溃。 - Apoorv Pandey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接