Creating a Flutter cellular app entails rendering some UI components that get modified in keeping with the user-initiated contact occasions , so we regularly want to make use of the person system’s {hardware} parts through platform-specific SDKs.
Each cellular platform provides inbuilt APIs to entry {hardware} parts and core working system options. For instance, for those who construct a local Android app with Kotlin, you need to use the Vibrator
class from the Android SDK to make the person’s system vibrate.
You should utilize your current Kotlin/Java-based shared libraries inside native Kotlin-based Android apps. However what if it’s essential name this platform-specific Kotlin code out of your Flutter app?
Flutter enables you to use Dart’s inbuilt cross-platform normal library for general-purpose programming necessities (i.e., I/O, Math, and so on.). It additionally provides the platform channels API to speak with platform-specific code to make use of operating-system-level APIs or invoke code segments written within the native app improvement language.
On this tutorial, I’ll clarify how one can name Kotlin code from the Dart aspect through the Flutter platform channels’ MethodChannel
class. Additionally, I’ll clarify how one can do event-driven Flutter-Native communications through EventChannel
.
Soar forward:
Highlighted options of MethodChannel
Flutter provides the MethodChannel
Dart class for builders to invoke platform-specific native code from the Flutter atmosphere. Additionally, Flutter provides you the required APIs to ship knowledge again to Flutter from the native host app code. Test the next highlighted options that MethodChannel
provides:
Cross-platform assist
We’ll focus on how one can invoke Kotlin code from Flutter, however the Flutter framework implementation enables you to name native code on iOS, Linux, macOS, and Home windows. So, calling Swift/Goal-C and C/C++ code can be attainable.
Efficiency-first design
Flutter doesn’t use embedded JavaScript execution environments, not like different standard cross-platform app improvement frameworks. Additionally, it makes use of AOT (ahead-of-time) compilation for launch binaries to realize near-native efficiency.
Equally, the Flutter workforce designed the Flutter-Native communication technique with a performance-first, binary messaging protocol for higher app efficiency. So, utilizing Kotlin and Dart on Android for accessing the Android SDK has no seen efficiency distinction!
Bi-directional communication assist
The Dart-based MethodChannel
class helps you name platform-specific code from Flutter. Alternatively, Flutter exposes platform-specific MethodChannel
API to name Dart code from the native aspect. So, you can also make a bi-directional communication line between your Dart code and platform-specific native code.
Automated data-type mapping
Flutter’s low-level platform channels API makes use of a binary messaging protocol, so all technique calls are remodeled right into a byte stream through the Dart-to-Native communication (see how Android type-conversion implementation makes use of ByteBuffer
right here). Flutter routinely removes knowledge information from the byte stream and generates language-specific knowledge varieties within the Dart and native finish. So, you possibly can switch your Dart-based knowledge to Kotlin/Java knowledge, and vice-versa as you’re employed with one language, though there are two totally different environments. Furthermore, the kind conversion characteristic is on the market for all supported platforms.
Error-handling options
Platform-specific APIs usually throw exceptions or return error codes for sudden or failure occasions. On the native aspect, we will simply use native SDK error-handling methods, however what can we do from the Dart aspect? MethodChannel
comes with inbuilt-error dealing with assist and throws Dart exceptions. Additionally, you need to use error codes from exception cases to enhance the error-handling technique in order for you.
Flutter MethodChannel
‘s structure
You’ve presumably simply learn an summary of MethodChannel
and the Flutter platform channels API’s objectives. The Flutter framework is comprised of two key parts: the Dart framework and the Flutter engine.
The Dart framework consists of an inbuilt widgets toolkit implementation, and the Flutter engine implements native host apps that embed the Dart framework. The platform channels API connects these two parts along with a bi-directional communication line.
The MethodChannel
implementation, part of the platform channels API enables you to execute and extract the results of named strategies on Dart and native code.
Now, you understand the architectural points of MethodChannel
. You may learn extra about the whole Flutter structure from this text and the official documentation.
Let’s get began with sensible functions!
Establishing a brand new mission
On this part, we’ll construct a pattern Flutter app and prolong it in keeping with varied sensible necessities to know how one can use MethodChannel
for connecting Kotlin and Dart collectively.
First, create a brand new Flutter mission with the next command:
flutter create flutter_platform_channels_demo cd flutter_platform_channels_demo
Run the newly generated app with the flutter run
command to test that every thing works.
You may examine the native Android host app supply by opening the android/app
listing. By default, the flutter create
command generates a Kotlin-based host app , and you could find the Android app’s Kotlin code in MainActivity.kt
. You gained’t see a lot code there, however you’ll discover it implements the FlutterActivity
class, part of the Flutter engine.
Now, we will begin modifying the MainActivity
Kotlin class to construct up a technique channel to attach with the Dart aspect.
Calling Kotlin code from Dart
We all know that we will generate a random quantity inside Dart, however let’s name the Kotlin normal library’s random quantity generator from the Dart aspect to get began with MethodChannel
.
First, we have to register a technique name handler from the Kotlin aspect. Add the next code to your MainActivity.kt
:
package deal com.instance.flutter_platform_channels_demo import kotlin.random.Random import androidx.annotation.NonNull import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.widespread.MethodChannel class MainActivity: FlutterActivity() { override enjoyable configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { tremendous.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "instance.com/channel").setMethodCallHandler { name, end result -> if(name.technique == "getRandomNumber") { val rand = Random.nextInt(100) end result.success(rand) } else { end result.notImplemented() } } } }
Right here, we override the configureFlutterEngine
technique from the FlutterActivity
class to register a technique channel for constructing a communication line with Dart. The configureFlutterEngine
technique will get invoked when the Flutter engine is initialized with a selected Android Exercise occasion, so Flutter recommends utilizing it to register technique channel handlers.
A way channel is sort of a namespace that consists of a number of technique signatures, so you need to use one technique channel to implement a number of native strategies. On this state of affairs, we applied the getRandomNumber
technique for demonstration functions. When the actual technique channel receives a technique name, we will determine the strategy title utilizing a conditional assertion:
if(name.technique == "getRandomNumber") { val rand = Random.nextInt(100) end result.success(rand) } // --- // ---
Right here, we use the end result.success
technique to return the generated random quantity to the Dart atmosphere. Although we don’t present invalid technique names intentionally from Dart, it’s all the time good to deal with unknown technique calls as follows:
// --- else { end result.notImplemented() }
Now, the native implementation is able to obtain technique calls from Dart. We’ll modify Flutter’s default demo app to show a random quantity generated from Kotlin. After we press the floating motion button, we see a brand new random quantity.
Extra nice articles from LogRocket:
Add the next code to your fundamental.dart
:
import 'package deal:flutter/providers.dart'; import 'package deal:flutter/materials.dart'; void fundamental() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({tremendous.key}); @override Widget construct(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colours.blue, ), residence: const MyHomePage(title: 'Flutter Demo Dwelling Web page'), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({tremendous.key, required this.title}); remaining String title; @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { int _counter = 0; static const platform = MethodChannel('instance.com/channel'); Future<void> _generateRandomNumber() async { int random; attempt { random = await platform.invokeMethod('getRandomNumber'); } on PlatformException catch (e) { random = 0; } setState(() { _counter = random; }); } @override Widget construct(BuildContext context) { return Scaffold( appBar: AppBar( title: Textual content(widget.title), ), physique: Middle( youngster: Column( mainAxisAlignment: MainAxisAlignment.middle, youngsters: <Widget>[ const Text( 'Kotlin generates the following number:', ), Text( '$_counter', style: Theme.of(context).textTheme.headline4, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _generateRandomNumber, tooltip: 'Generate', youngster: const Icon(Icons.refresh), ), ); } }
We created a MethodChannel
occasion within the Dart atmosphere as follows:
static const platform = MethodChannel('instance.com/channel');
Notice that we should always go the precise technique channel title we used within the Kotlin code — in any other case, the particular technique name will throw a MissingPluginException
.
We invoke the _generateRandomNumber
technique when the person presses the floating motion button. When the actual technique will get invoked, the app sends a message to the strategy channel through platform.invokeMethod(‘getRandomNumber’)
. Internally, the Flutter engine triggers the strategy channel handler and executes the Kotlin-based random quantity era code we wrote earlier than.
Run the app and see the pattern app in motion:
Returning knowledge from Kotlin to Dart
Within the earlier instance, we returned an integer from Kotlin to Dart. After we present a Kotlin Int
sort to a selected technique name, Flutter routinely converts it to a Dart int
sort.
Equally, Flutter’s Technique Channel
implementation routinely converts all atomic varieties and a few complicated inbuilt objects as properly, akin to Kotlin Listing
and HashMap
. The next desk from the Flutter documentation lists all supported computerized sort conversions:
Dart | Kotlin |
---|---|
null | null |
bool | Boolean |
int | Int |
int | Lengthy |
double | Double |
String | String |
Uint8List | ByteArray |
Int32List | IntArray |
Int64List | LongArray |
Float32List | FloatArray |
Float64List | DoubleArray |
Listing | Listing |
Map | HashMap |
Let’s attempt to use Kotlin’s String
sort and see what occurs from the Dart aspect. Use the next code to generate a random string from Kotlin in MainActivity.kt
:
override enjoyable configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { tremendous.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "instance.com/channel").setMethodCallHandler { name, end result -> if(name.technique == "getRandomString") { val rand = ('a'..'z').shuffled().take(4).joinToString("") end result.success(rand) } else { end result.notImplemented() } } }
We return a four-character-long random string for the getRandomString
technique for the Dart aspect. Now, modify your fundamental.dart
file to simply accept a string worth from Kotlin as follows:
import 'package deal:flutter/providers.dart'; import 'package deal:flutter/materials.dart'; void fundamental() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({tremendous.key}); @override Widget construct(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colours.blue, ), residence: const MyHomePage(title: 'Flutter Demo Dwelling Web page'), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({tremendous.key, required this.title}); remaining String title; @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { String _counter=""; static const platform = MethodChannel('instance.com/channel'); Future<void> _generateRandomString() async { String random = ''; attempt { random = await platform.invokeMethod('getRandomString'); print(random.runtimeType); } on PlatformException catch (e) { random = ''; } setState(() { _counter = random; }); } @override Widget construct(BuildContext context) { return Scaffold( appBar: AppBar( title: Textual content(widget.title), ), physique: Middle( youngster: Column( mainAxisAlignment: MainAxisAlignment.middle, youngsters: <Widget>[ const Text( 'Kotlin generates the following string:', ), Text( '$_counter', style: Theme.of(context).textTheme.headline4, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _generateRandomString, tooltip: 'Generate', youngster: const Icon(Icons.refresh), ), ); } }
The above code makes use of print(random.runtimeType)
to test the output knowledge sort of the invokeMethod
technique. On this case, we obtain a string from the Kotlin aspect and show on the Flutter app display screen. Run the above code and press the floating motion button to generate random strings through Kotlin:
When you test your terminal display screen, you need to see that the print
operate outputs String
as the information sort of the random
variable; if that is so, then we all know the kind conversion labored.
Experiment with the opposite primitive knowledge varieties. I’ll clarify how one can switch complicated knowledge varieties and objects between Kotlin and Dart in an upcoming part of this tutorial.
Passing arguments from Dart to Kotlin
We already mentioned how one can return knowledge from Kotlin with success
technique calls. What if it’s essential ship some knowledge to Kotlin from Dart?
We usually use technique parameters once we name a technique in a selected programming language — and the identical method works with Flutter technique channels! You may go named parameters through the invokeMethod
technique utilizing a Dart dynamic map.
Assume that you must configure the random string era course of from the Dart aspect. For instance, we will ship the string size and a prefix from the Flutter app code.
First, determine the required parameters:
len
: Random string sizeprefix
: A prefix for the random string
Ship these parameters with values through _generateRandomString
:
Future<void> _generateRandomString() async { String random = ''; attempt { var arguments = { 'len': 3, 'prefix': 'fl_', }; random = await platform.invokeMethod('getRandomString', arguments); } on PlatformException catch (e) { random = ''; } setState(() { _counter = random; }); }
Subsequent, replace the Kotlin code to devour the named parameters:
if(name.technique == "getRandomString") { val restrict = name.argument("len") ?: 4 val prefix = name.argument("prefix") ?: "" val rand = ('a'..'z') .shuffled() .take(restrict) .joinToString(prefix = prefix, separator = "") end result.success(rand) }
The above code makes use of Kotlin’s Elvis operator [?:]
to set default values for restrict
and prefix
constants. Run the app. You will note random strings based mostly on parameters we’ve offered from the Dart aspect of the strategy channel:
Experiment additional utilizing varied values for technique parameters and attempt to add extra parameters.
If it’s essential go one technique parameter, you possibly can straight go the actual parameter with out making a dynamic map for higher readability. See how the next code snippet sends the random string size:
// Dart: random = await platform.invokeMethod('getRandomString', 3); // Kotlin val restrict = name.arguments() ?: 4 val rand = ('a'..'z') .shuffled() .take(restrict) .joinToString("") end result.success(rand)
Error dealing with methods
There are two main error-handling methods in programming: error code-based and exceptions-based. Some programmers use a hybrid error-handling technique by mixing each.
MethodChannel
has inbuilt assist to deal with exceptions from Dart for the Kotlin aspect’s error flows. Additionally, it provides a technique to distinguish native error varieties with error codes in exception cases. In different phrases, MethodChannel
provides a hybrid error-handling technique for Flutter builders.
In earlier examples, we used the end result.success
technique to return a price and end result.notImplemented
to deal with unknown technique calls, which can throw MissingPluginException
in Dart.
What if we have to make a Dart exception from the Kotlin aspect? The end result.error
technique helps you throw a Dart PlatformException
occasion from Kotlin. Assume that we have to throw an exception if we offer a destructive worth for the random string size within the earlier instance.
First, replace the Kotlin code as follows to inform Dart in regards to the exception:
if(name.technique == "getRandomString") { val restrict = name.arguments() ?: 4 if(restrict < 0) { end result.error("INVALIDARGS", "String size shouldn't be a destructive integer", null) } else { val rand = ('a'..'z') .shuffled() .take(restrict) .joinToString("") end result.success(rand) } }
Right here, we offer a novel exception code and message through end result.error
. Subsequent, catch the exception and use it throughout the Dart aspect as follows:
Future<void> _generateRandomString() async { String random = ''; attempt { random = await platform.invokeMethod('getRandomString', -5); } on PlatformException catch (e) { random = ''; print('PlatformException: ${e.code} ${e.message}'); } setState(() { _counter = random; }); }
While you run the app and press the floating motion button, you will notice the exception code and message in your terminal as a result of we handed -5
because the string size from the Dart aspect:
As we noticed within the above instance, you possibly can catch PlatformException
in Dart, and you may test the error code within the exception occasion for dealing with technique channel errors. One other extra summary method is to make your individual exception occasion based mostly on Kotlin error codes. Test the Flutter digital camera plugin’s CameraException
as a reference implementation.
Invoking native SDK capabilities through MethodChannel
Now, we all know how one can use MethodChannel
to invoke Kotlin code from Dart. We’ve used Kotlin’s normal library options in earlier demonstrations. Equally, you possibly can reuse your pre-implemented Kotlin/Java libraries with the Flutter platform channels. Utilizing native SDKs can be attainable with technique channels, and that’s the principle aim behind Flutter’s platform channels implementation.
Flutter already helps system darkish theme dealing with and has plugins for different native SDKs, however let’s invoke some native SDK APIs to know MethodChannel
use instances additional.
We’ll write a local technique to test whether or not the darkish theme is on or not. First, implement a brand new technique in Flutter technique channels with Kotlin in your MainActivity.kt
:
package deal com.instance.flutter_platform_channels_demo import kotlin.random.Random import androidx.annotation.NonNull import android.content material.res.Configuration import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.widespread.MethodChannel class MainActivity: FlutterActivity() { override enjoyable configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { tremendous.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "instance.com/channel").setMethodCallHandler { name, end result ->sucess if(name.technique == "isDarkMode") { val mode = getContext() .getResources() .getConfiguration().uiMode and Configuration.UI_MODE_NIGHT_MASK end result.success(mode == Configuration.UI_MODE_NIGHT_YES) } else { end result.notImplemented() } } } }
Right here we used the uiMode
bit masks from the Android SDK’s Configuration API to detect the system theme. Subsequent, use the isDarkMode
technique from Dart by updating the _MyHomePageState
implementation:
class _MyHomePageState extends State<MyHomePage> { String _theme=""; static const platform = MethodChannel('instance.com/channel'); Future<void> _findColorTheme() async { bool isDarkMode; attempt { isDarkMode = await platform.invokeMethod('isDarkMode'); } on PlatformException catch (e) { isDarkMode = false; print('PlatformException: ${e.code} ${e.message}'); } setState(() { _theme = isDarkMode ? 'darkish' : 'mild'; }); } @override Widget construct(BuildContext context) { return Scaffold( appBar: AppBar( title: Textual content(widget.title), ), physique: Middle( youngster: Column( mainAxisAlignment: MainAxisAlignment.middle, youngsters: <Widget>[ const Text( 'System color theme:', ), Text( _theme, style: Theme.of(context).textTheme.headline4, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _findColorTheme, tooltip: 'Discover colour theme', youngster: const Icon(Icons.refresh), ), ); } }
Check the app by altering your system colour theme as follows:
Equally, you possibly can name any Android SDK APIs from Dart through Flutter platform channels.
Utilizing the EventChannel
class
The MethodChannel
class offers a request-response-based communication resolution as conventional RESTful APIs do. What if we have to name purchasers from the server once we work with internet functions? Then, we have a tendency to decide on an event-driven communication mechanism like WebSockets. The EventChannel
class provides an asynchronous occasion stream for constructing an event-driven communication line between the native host app and Flutter. The EventChannel
class is usually used to ship native occasions to the Dart aspect.
For instance, we will dispatch the system theme change occasion from Kotlin to Dart. Additionally, we will use EventChannel
to broadcast frequent occasions from the system’s sensors.
Earlier, we needed to press the floating motion button to detect the present system colour theme. Now, we’ll enhance our app by including an EventChannel
occasion to deal with it routinely.
First, add the next code to your MainActivity.kt
:
package deal com.instance.flutter_platform_channels_demo import kotlin.random.Random import androidx.annotation.NonNull import android.os.Bundle import android.content material.res.Configuration import android.content material.pm.ActivityInfo import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.widespread.EventChannel import io.flutter.plugin.widespread.EventChannel.EventSink import io.flutter.plugin.widespread.EventChannel.StreamHandler class MainActivity: FlutterActivity() { var occasions: EventSink? = null var oldConfig: Configuration? = null override enjoyable onCreate(savedInstanceState: Bundle?) { tremendous.onCreate(savedInstanceState) oldConfig = Configuration(getContext().getResources().getConfiguration()) } override enjoyable configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { tremendous.configureFlutterEngine(flutterEngine) EventChannel(flutterEngine.dartExecutor.binaryMessenger, "instance.com/channel").setStreamHandler( object: StreamHandler { override enjoyable onListen(arguments: Any?, es: EventSink) { occasions = es occasions?.success(isDarkMode(oldConfig)) } override enjoyable onCancel(arguments: Any?) { } } ); } override enjoyable onConfigurationChanged(newConfig: Configuration) { tremendous.onConfigurationChanged(newConfig) if(isDarkModeConfigUpdated(newConfig)) { occasions?.success(isDarkMode(newConfig)) } oldConfig = Configuration(newConfig) } enjoyable isDarkModeConfigUpdated(config: Configuration): Boolean { return (config.diff(oldConfig) and ActivityInfo.CONFIG_UI_MODE) != 0 && isDarkMode(config) != isDarkMode(oldConfig); } enjoyable isDarkMode(config: Configuration?): Boolean { return config!!.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES } }
We use the EventChannel
class to create an event-driven communication stream. As soon as the EventChannel
handler is hooked up, we will use the EventSink
occasion to ship occasions to the Dart aspect. Occasions happen within the following conditions:
- When the Flutter app is initialized, the occasion channel will obtain a brand new occasion with the present theme standing
- When the person goes again to the app after altering the system theme from the settings app, the occasion channel will obtain a brand new occasion with the present theme standing
Notice that right here we use a boolean worth because the occasion payload to determine whether or not the darkish mode is activated or not. Now, add the next code to your fundamental.dart
file and full the implementation:
import 'package deal:flutter/providers.dart'; import 'package deal:flutter/materials.dart'; void fundamental() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({tremendous.key}); @override Widget construct(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData(), darkTheme: ThemeData.darkish(), themeMode: ThemeMode.system, residence: const MyHomePage(title: 'Flutter Demo Dwelling Web page'), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({tremendous.key, required this.title}); remaining String title; @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { String _theme=""; static const occasions = EventChannel('instance.com/channel'); @override void initState() { tremendous.initState(); occasions.receiveBroadcastStream().hear(_onEvent); } void _onEvent(Object? occasion) { setState(() { _theme = occasion == true ? 'darkish' : 'mild'; }); } @override Widget construct(BuildContext context) { return Scaffold( appBar: AppBar( title: Textual content(widget.title), ), physique: Middle( youngster: Column( mainAxisAlignment: MainAxisAlignment.middle, youngsters: <Widget>[ const Text( 'System color theme:', ), Text( _theme, style: Theme.of(context).textTheme.headline4, ), ], ), ), ); } }
The above code connects with the occasion channel we created earlier than and shows the present theme. The EventChannel
implementation triggers the _onEvent
callback every time it receives a brand new occasion from the Kotlin aspect.
Run the app and activate/deactivate darkish mode. You need to see the theme title on the app display screen, as proven within the following preview:
You’ll discover the app colour scheme is modified based mostly on the present theme. This conduct occurs as a result of we used ThemeMode.system
for themeMode
to make the Flutter app conscious of the present system theme, and this conduct isn’t a results of the EventChannel
API utilization.
Sending/receiving complicated objects
The Flutter platform channels API routinely converts inbuilt complicated varieties, like maps and lists. However, in some situations, we have to go much more complicated objects with many knowledge information. You may contemplate the next methods for sending/receiving such complicated objects:
- Transferring the item knowledge as a map with primitive knowledge varieties. You could write a helper/utility technique to transform your complicated object to a map
- Serializing the item to a platform-independent format like JSON and deserializing it earlier than use
- Writing a customized codec for serialization/deserialization. Test
FirestoreMessageCodec
as a reference implementation
Packaging native code modifications
Flutter enables you to modify the native host app and construct a communication line with Dart through platform channels APIs. On this tutorial, we realized MethodChannel
by updating the Kotlin-based host app straight. You can also use the identical method to reuse your Kotlin/Java libraries, name Android SDK APIs, or invoke any Kotlin code phase. You may reuse native code modifications in different Flutter apps, typically.
For instance, for those who use MethodChannel
to vibrate the person’s system, it’s possible you’ll want the identical native implementation in your different apps. The Flutter SDK provides a fully-featured plugin system to create, publish, and combine shareable plugins.
Assume that it’s essential use the Kotlin-based random quantity generator technique in a number of Flutter apps. Then, you possibly can create a Flutter plugin and import it slightly than modifying each native host app. Test the official documentation to get began with Flutter plugin improvement and examine the shared_preferences
plugin to be taught the really helpful Flutter plugin construction.
MethodChannel
vs. EventChannel
vs. BasicMessageChannel
The BasicMessageChannel
class can be part of the Flutter platform channels API. It helps you implement low-level communication strains with customized codecs. Selecting essentially the most appropriate platform channels class for connecting Kotlin with Dart will assist encourage you to maintain your codebase readable, environment friendly, and minimal.
Take a look at the next comparability desk:
Comparability issue | MethodChannel |
EventChannel |
BasicMessageChannel |
Communication sort | Request-response (RPC-like) sort technique invocation | Occasion-driven stream | Low-level messages |
Path | Bi-directional | Bi-directional | Bi-directional |
An instance generic use case | Calling native codes | Subscribing to native occasions | Implementing customized codecs |
Conclusion
We studied the Flutter platform channels API and examined the MethodChannel
class with sensible examples on this tutorial. Additionally, we turned accustomed to the EventChannel
class that helps us create event-driven communication streams with the native host app. This tutorial targeted on calling Kotlin code from Flutter, however the Flutter framework enables you to name different platform languages too.
We usually should name Kotlin code both to reuse it or to name Android SDK capabilities. When you’ve migrated to Flutter from a local Android app, however you continue to have a number of enterprise logic written in a Kotlin/Java package deal or it’s essential reuse your Java-based internet API’s enterprise logic, you need to use MethodChannel
for calling your current Kotlin code effectively. For many Android SDK capabilities, you could find pre-implemented plugins. So, test current open supply group plugins earlier than making a MethodChannel
for calling native SDKs.
The MethodChannel
API doesn’t provide code era, so we’ve got to make use of conditional statements to differentiate technique calls and go arguments through dynamic Dart maps. Moreover, it doesn’t assure sort security. When you search such options, take a look at the pigeon
package deal.
Total, the MethodChannel
API is an environment friendly, minimal, dynamic, and inbuilt mechanism that we will use to name Kotlin code out of your Flutter app.
LogRocket: Full visibility into your internet and cellular apps
LogRocket is a frontend utility monitoring resolution that allows you to replay issues as in the event that they occurred in your individual browser. As a substitute of guessing why errors occur, or asking customers for screenshots and log dumps, LogRocket enables you to replay the session to shortly perceive what went improper. It really works completely with any app, no matter framework, and has plugins to log extra context from Redux, Vuex, and @ngrx/retailer.
Along with logging Redux actions and state, LogRocket information console logs, JavaScript errors, stacktraces, community requests/responses with headers + our bodies, browser metadata, and customized logs. It additionally devices the DOM to file the HTML and CSS on the web page, recreating pixel-perfect movies of even essentially the most complicated single-page and cellular apps.