I am working on a plugin for Flutter with background stuff.
Recently, I faced somethings about Flutter android embedding in the android_alarm_manager plugin
Flutter published a new version of its Android embedding. This is the Android code that is responsible for integrating Flutter within an Android app. It includes classes like FlutterActivity
, FlutterFragment
, FlutterView
, and FlutterEngine
. The v2 Android embedding includes support for standard Android lifecycle events and the separation of Flutter execution from the Android UI, which were missing in the v1 Android embedding. During the development of the v2 Android embedding it became clear that the existing API for Flutter plugins was insufficient to handle the new capabilities of the v2 Android embedding. A new Android plugin API was needed.
In the old v1 Android embedding, all plugins were initialized and configured at the very beginning of the Android app and there was only ever one Flutter experience. In the v2 embedding, we make no assumption about when a plugin is initialized, and a plugin must be initialized once per FlutterEngine. As a result, all Flutter plugins for Android must now support instantiation instead of static initialization, and they must support being attached to, and detached from a FlutterEngine. The following code samples demonstrate the difference between the old v1 plugin initialization implementation and the new v2 plugin initialization process.
Old plugin initialization
class MyOldPlugin {
public static void registerWith(PluginRegistrar registrar) {
// Obtain any references that the plugin requires from the
// registrar.
//
// This plugin is now considered "initialized" and "attached"
// to a Flutter experience.
}
}
New plugin initialization
class MyNewPlugin implements FlutterPlugin {
public MyNewPlugin() {
// All Android plugin classes must support a no-args
// constructor. A no-arg constructor is provided by
// default without declaring one, but we include it here for
// clarity.
//
// At this point your plugin is instantiated, but it
// isn't attached to any Flutter experience. You should not
// attempt to do any work here that is related to obtaining
// resources or manipulating Flutter.
}
@override
public void onAttachedToFlutterEngine(FlutterPluginBinding binding) {
// Your plugin is now attached to a Flutter experience
// represented by the given FlutterEngine.
//
// You can obtain the associated FlutterEngine with
// binding.getFlutterEngine()
//
// You can obtain a BinaryMessenger with
// binding.getBinaryMessenger()
//
// You can obtain the Application context with
// binding.getApplicationContext()
//
// You cannot access an Activity here because this
// FlutterEngine is not necessarily displayed within an
// Activity. See the ActivityAware interface for more info.
}
@override
public void onDetachedFromFlutterEngine(FlutterPluginBinding binding) {
// Your plugin is no longer attached to a Flutter experience.
// You need to clean up any resources and references that you
// established in onAttachedToFlutterEngine().
}
}
Additionally, your plugin must not depend upon an Activity reference within onAttachedToFlutterEngine(). Just because your plugin is attached to a Flutter experience doesn’t mean that the Flutter experience is being displayed in an Activity. This is one of the most significant differences between the old and new plugin APIs. In the old v1 plugin API, plugin authors could depend upon an Activity being available immediately and permanently. This is no longer true.
For more info, see https://medium.com/flutter/modern-flutter-plugin-development-4c3ee015cf5a