Using native code in a Flutter application is done through Platform Channels, FFI, or Platform Plugins. Below is a clear, step-by-step guide explaining all approaches.
โ 1. Using Platform Channels (Most Common Way)
Use MethodChannel in Flutter to communicate with Kotlin/Java (Android) and Swift/Objective-C (iOS).
๐น Step 1: Create a MethodChannel in Flutter
import 'package:flutter/services.dart';
class NativeHelper {
static const platform = MethodChannel('com.example/native');
static Future<String> getNativeMessage() async {
final message = await platform.invokeMethod('getMessage');
return message;
}
}
๐น Step 2: Call Native Method from Flutter
ElevatedButton(
onPressed: () async {
final msg = await NativeHelper.getNativeMessage();
print(msg);
},
child: Text("Call Native Code"),
)
โ 2. Add Native Code in Android (Kotlin/Java)
Android โ Kotlin Example
Path: android/app/src/main/kotlin/.../MainActivity.kt
package com.example.nativecode
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
class MainActivity: FlutterActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "com.example/native")
.setMethodCallHandler { call, result ->
if (call.method == "getMessage") {
result.success("Hello from Android Native Code!")
} else {
result.notImplemented()
}
}
}
}
โ 3. Add Native Code in iOS (Swift)
Path: ios/Runner/AppDelegate.swift
import UIKit
import Flutter
@UIApplicationMain
class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
let controller = window?.rootViewController as! FlutterViewController
let channel = FlutterMethodChannel(name: "com.example/native", binaryMessenger: controller.binaryMessenger)
channel.setMethodCallHandler { (call, result) in
if call.method == "getMessage" {
result("Hello from iOS Native Code!")
} else {
result(FlutterMethodNotImplemented)
}
}
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
๐ Output
When Flutter calls getNativeMessage():
- Android returns โ “Hello from Android Native Code!”
- iOS returns โ “Hello from iOS Native Code!”
โ 4. Using FFI (Dart โ C/C++ native code)
Use when performance is critical (like encryption, video processing, audio processing).
Example structure:
/flutter_project
/native_lib
- mylib.c
Dart side:
import 'dart:ffi';
import 'dart:io';
typedef NativeAddFunc = Int32 Function(Int32, Int32);
typedef AddFunc = int Function(int, int);
final dylib = Platform.isAndroid
? DynamicLibrary.open('libmylib.so')
: DynamicLibrary.process();
final addPointer = dylib.lookup<NativeFunction<NativeAddFunc>>('add');
final add = addPointer.asFunction<AddFunc>();
void main() {
print(add(10, 20)); // prints 30
}
โ 5. Create a Flutter Plugin (Reusable native code)
Use when your native feature will be reused in multiple apps.
flutter create --template=plugin my_native_plugin
This scaffolds native code folders for Android & iOS.
๐ Summary Table
| Requirement | Best Method |
|---|---|
| Communicate with Android/iOS | Platform Channels |
| High-performance native library (C/C++/Rust) | Dart FFI |
| Reusable native SDK (plugins) | Flutter Plugin |
| Access OS features (camera, sensors, storage) | Platform Channels / Plugins |
1 Comment
How to delete your Google AdMob Account - Dheeraj Hitech · December 14, 2025 at 12:51 pm
[…] In Account settings, click Account information […]