-
Notifications
You must be signed in to change notification settings - Fork 26.8k
Experimental: Create Flutter Plugin
These instructions are for the ecosystem team as they implement parallel plugin support for the new embedding.
-
Create a new
[MyPlugin].java
file atdev.flutter.plugins.[myplugin]
. -
Have
[MyPlugin]
implementFlutterPlugin
. -
(Optional) If your plugin needs an
Activity
reference, also implementActivityAware
. -
(Optional) If your plugin is expected to be held in a background
Service
at any point in time, implementServiceAware
. -
Implement each plugin method as desired. Set up references as you attach to things. Clean up references as you detach from things.
-
Consider separating the
MethodChannelHandler
from the old version of[MyPlugin]
and then use thatMethodChannelHandler
in bothio.flutter.plugins.[myplugin].[MyPlugin].java
anddev.flutter.plugins.[myplugin].[MyPlugin].java
. -
Add a static
registerWith()
method to your new[MyPlugin]
class and have it call through to theregisterWith()
method in your old[MyPlugin]
class. -
(Optional but Recommended) Add unit tests to validate the serialization/deserialization of all incoming/outgoing channel messages.
To get started with a Flutter Android plugin in code, start by implementing FlutterPlugin
.
public class MyPlugin implements FlutterPlugin {
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
// TODO: your plugin is now attached to a Flutter experience.
}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
// TODO: your plugin is no longer attached to a Flutter experience.
}
}
As shown above, your plugin may or may not be associated with a given Flutter experience at any given moment in time. You should take care to initialize your plugin's behavior in onAttachedToEngine()
, and then cleanup your plugin's references in onDetachedFromEngine()
.
The FlutterPluginBinding
provides your plugin with a few important references:
-
binding.getFlutterEngine()
: Returns theFlutterEngine
that your plugin is attached to, providing access to components like theDartExecutor
,FlutterRenderer
, and more. -
binding.getApplicationContext()
: Returns the Android application'sContext
for the running app. -
binding.getLifecycle()
: Returns a reference that can be used to obtain aLifecycle
object. If you need to use this lifecycle reference then you need add a project dependency on Flutter's Android lifecycle package.
If your plugin needs to interact with the UI, such as requesting permissions, or altering Android UI chrome, then you need to take additional steps to define your plugin. You must implement the ActivityAware
interface.
public class MyPlugin implements FlutterPlugin, ActivityAware {
//...normal plugin behavior is hidden...
@Override
public void onAttachedToActivity(ActivityPluginBinding activityPluginBinding) {
// TODO: your plugin is now attached to an Activity
}
@Override
public void onDetachedFromActivityForConfigChanges() {
// TODO: the Activity your plugin was attached to was destroyed to change configuration.
// This call will be followed by onReattachedToActivityForConfigChanges().
}
@Override
public void onReattachedToActivityForConfigChanges(ActivityPluginBinding activityPluginBinding) {
// TODO: your plugin is now attached to a new Activity after a configuration change.
}
@Override
public void onDetachedFromActivity() {
// TODO: your plugin is no longer associated with an Activity. Clean up references.
}
}
To interact with an Activity
, your ActivityAware
plugin must implement appropriate behavior at 4 stages. First, your plugin is attached to an Activity
. You can access that Activity
and a number of its callbacks through the provided ActivityPluginBinding
.
Since Activity
s can be destroyed during configuration changes, you must cleanup any references to the given Activity
in onDetachedFromActivityForConfigChanges()
, and then re-establish those references in onReattachedToActivityForConfigChanges()
.
Finally, in onDetachedFromActivity()
your plugin should clean up all references related to Activity
behavior and return to a non-UI configuration.
TODO
TODO
- Home of the Wiki
- Roadmap
- API Reference (stable)
- API Reference (main)
- Glossary
- Contributor Guide
- Chat on Discord
- Design documents
- Code of Conduct
- Issue triage reports (latest)
- Our Values
- Tree hygiene
- Issue hygiene and Triage
- Style guide for Flutter repo
- Project teams
- Contributor access
- What should I work on?
- Popular issues
- Running and writing tests
- Release process
- Flutter Framework Gardener Rotation
- Rolling Dart
- Manual Engine Roll with Breaking Commits
- Updating Material Design Fonts & Icons
- Postmortems and Retrospectives
- Hotfix Documentation Best Practices
- In case of emergency
- Landing Changes With Autosubmit
- Setting up the Framework development environment
- The Framework architecture
- API Docs code block generation
- Running examples
- Using the Dart analyzer
- The flutter run variants
- Test coverage for package:flutter
- Writing a golden-file test for package:flutter
- Managing template image assets
- Setting up the Engine development environment
- Compiling the engine
- Debugging the engine
- Using Sanitizers with the Flutter Engine
- Testing the engine
- The Engine architecture
- Flutter's modes
- Crashes
- more...
- Setting up the Packages development environment
- Plugins and Packages repository structure
- Contributing to Plugins and Packages
- Understanding Packages tests
- Plugin Tests
- Releasing a Plugin or Package
- more...