How Does Flutter Communicate With Platform Native Code?

Exploring the different channels that Flutter uses to access platform code.


Dedan Ndungu

a year ago | 3 min read

Uploaded by Christopher on Unsplash

Flutter does an incredible job of creating cross-platform applications. With many plugins readily available, accessing native capabilities and features is easy and takes little time.

But what happens when the plugin is not up to the task, there is no plugin yet for the job you are doing, or you need to have your custom implementation.

Well, this is what happens: you need to write native code for each platform you are targeting and relay data back and forth between the native code and the flutter framework. Sounds hard? But worry not, because in this article you are gonna learn how to do it seamlessly.

Platform Channels for Communication

Flutter uses a flexible message-passing style to communicate between your dart code and the native code of your application host. The Flutter app sends messages to its host over a platform channel. The host listens on the platform channel and receives the message, executes native code, and sends a response back to the Flutter code. All this happens asynchronously to maintain app responsiveness.

All messages are encoded into binary before being sent, and binary results received are decoded into Dart values.

Types of platform channels APIs

Flutter offers various channels to communicate with platform-specific code. Depending on your needs, and the type of platform-specific code you are interacting with, you can choose any of the following or a mix to work with.

All the channels require a name passed to their constructors which connects the client and host sides. The name must be unique and a naming scheme is encouraged.
  1. BasicMessageChannelA named channel for communicating with platform plugins using asynchronous message passing.

It is the simplest platform channel that takes a MessageCodec that encodes and decodes the data passed. Flutter provides four types of codecs namely StringCodec, BinaryCodec, JSONMessageCodec and StandardMessageCodec.

final messageChannel = BasicMessageChannel<String>(‘platform.testing/sensor_support’, StringCodec());

2. MethodChannelA named channel for communicating with platform plugins using asynchronous method calls.

It is the most common platform channel that suits most use cases. It provides a way to execute a function in the native code and get a result back.

final methodChannel = MethodChannel('platform.testing/method_calls');```

3. EventChannelA named channel for communicating with platform plugins using event streams.

It is suited to listen to changes on the native code that updates your Dart stream whenever a change occurs.

final eventChannel = EventChannel(‘platform.testing/light_sensor’);

With the above information, you are ready to start writing some code. We are going to build an app that can detect the intensity of light (Illuminance) in a place. Using the light sensors on a mobile device we can achieve this.

Note: The article only targets the Android platform at the moment

Setting up Tip

For better debugging, while writing platform-specific and flutter code, I would advise you do the following:

  • Open the Flutter project using VS Code. You can run the app to view flutter logs and errors.
  • Open the android folder using Android Studio. You can run the app to view the android native logs as well as use breakpoints.


Add the following in the main manifest file to ask the user for permission.

<uses-permission android:name="android.permission.BODY_SENSORS" />


Add this dependency in the pubsec.yaml file to handle permission requests.

permission_handler: ^10.0.0

Flutter platform channel implementation

This is the dart and flutter code implementation. Please read through the comments to understand how it works.

Android Kotlin Implementation

Create a new file SensorActivity.kt in your android source folder. Paste the following contents into it.

This is the code implementation to handle the light sensor changes:

Next, we edit the contents of the MainActivity.kt file. This is where the FlutterEngine is configured and all plugins registered. The PlatformChannel APIs are also handled here.

The following code includes comments on how to go about it:

NOTE: Each message sent involves an asynchronous mandatory reply from the receiver. Dart always expects a response for every message passed for it`s future to complete.

With this, you have made the first step to integrating platform native code into your Flutter app. You can also write and publish your plugin.

That’s all for today, pips.

Happy coding!




Created by

Dedan Ndungu

Living on the Edge







Related Articles