为什么我的调用堆栈显示我有 2 个电源正在运行?

Mik*_*ink 6 android dart kotlin flutter firebase-cloud-messaging

我开始为 FCM 实现后台消息,他们要求我制作自己的 Kotlin 应用程序。但自从我这样做以来,我的调用堆栈中似乎有 2 个主要函数。

在此输入图像描述

这怎么可能?如果我运行一个空项目,它的调用堆栈中有 0 个电源吗?

我添加了Application.kt

package HERE_I_HAVE_MY_PACKAGE_NAME

import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService

public class Application: FlutterApplication(), PluginRegistrantCallback {
  override fun onCreate() {
    super.onCreate()
    FlutterFirebaseMessagingService.setPluginRegistrant(this)
  }

  override fun registerWith(registry: PluginRegistry) {
    FirebaseCloudMessagingPluginRegistrant.registerWith(registry)
  }
}
Run Code Online (Sandbox Code Playgroud)

和 FirebaseCloudMessagingPluginRegistrant.kt

package HERE_I_HAVE_MY_PACKAGE_NAME

import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin

class FirebaseCloudMessagingPluginRegistrant {
  companion object {
    fun registerWith(registry: PluginRegistry) {
      if (alreadyRegisteredWith(registry)) {
        return;
      }
      FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"))
    }

    fun alreadyRegisteredWith(registry: PluginRegistry): Boolean {
      val key = FirebaseCloudMessagingPluginRegistrant::class.java.name
      if (registry.hasPlugin(key)) {
        return true
      }
      registry.registrarFor(key)
      return false
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这是我的 AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.company_name.app_name">
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <!-- 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. -->
    <application
        android:name=".Application"
        android:label="App Name"
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            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">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
            <intent-filter>
                <action android:name="FLUTTER_NOTIFICATION_CLICK" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
        android:name="com.yalantis.ucrop.UCropActivity"
        android:screenOrientation="portrait"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
        <!-- 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" />
        <meta-data
            android:name="com.google.firebase.messaging.default_notification_channel_id"
            android:value="@string/default_notification_channel_id"/>  
    </application>
</manifest>
Run Code Online (Sandbox Code Playgroud)

cam*_*492 1

我不确定是什么原因main()导致运行多次(在我的例子中是 3 次),但我找到了解决方法

void main() {
  runApp(new MaterialApp(
    home: new BeforeRunning(),
  ));
}

class BeforeRunning extends StatefulWidget {
  BeforeRunning({Key key}) : super(key: key);

  @override
  _BeforeRunningState createState() => _BeforeRunningState();
}

class _BeforeRunningState extends State<BeforeRunning> {
  @override
  void initState() {
    super.initState();
    Timer(Duration(milliseconds: 10), () {
      Navigator.of(context).pushReplacement(new MaterialPageRoute(builder: (BuildContext context) => MyApp()));
    });
  }

  @override
  Widget build(BuildContext context) {    //You can add a splash screen here
    SystemChrome.setEnabledSystemUIOverlays([]);
    return Container(
      height: MediaQuery.of(context).size.height,
      width: MediaQuery.of(context).size.width,
      color: Colors.black,
    );
  }
}

class MyApp extends StatefulWidget {
  MyApp({Key key}) : super(key: key);

  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {
  //initState() here
  //build() here
}
Run Code Online (Sandbox Code Playgroud)

基本上,在 的 里面添加一个快速(10Timer()毫秒),从那时起任何屏幕都只会构建一次。(对我有用)BeforeRunning()initState()Navigator.of(context).pushReplacement( /*next screen*/)

main()BeforeRunning()运行多次,但Timer()不知何故停止了除一个线程之外的所有线程