Understanding Pigeon Methods in Flutter: A Complete Guide for Native Communication

Flutter is great—until you need to talk to native code.

If you’ve ever used MethodChannel, you’ve probably faced:

  • Runtime crashes
  • Map<dynamic, dynamic> casting errors
  • Hard-to-debug contracts between Flutter and native

Pigeon solves this problem by introducing type-safe, generated APIs between Flutter and native platforms.

This article explains Pigeon methods in detail:

  • What methods exist
  • How they work on native side
  • Who calls whom
  • Sync vs async
  • Real-world patterns

What is Pigeon?

Pigeon is a code generation tool from the Flutter team that creates:

  • Dart APIs
  • Kotlin / Java APIs (Android)
  • Swift / Objective-C APIs (iOS)

All from one shared Dart file.

Pigeon does not render UI. It enables safe, structured communication between Flutter and native code.


The Core Concept: Only Two Types of Pigeon Methods

Pigeon has exactly two method categories:

  1. HostApi → Flutter calls Native
  2. FlutterApi → Native calls Flutter

That’s it. No third type.


1️⃣ HostApi Methods (Flutter → Native)

What are HostApi methods?

  • Defined in Dart
  • Implemented in native
  • Called by Flutter

Think of them as commands.

Use cases

  • Start payment
  • Fetch device info
  • Open native screens
  • Trigger SDK actions

Dart Definition

@HostApi()
abstract class PaymentHostApi {
  void startPayment(String orderId);
  void cancelPayment();
}

Generated Native Code (Android – Kotlin)

interface PaymentHostApi {
  fun startPayment(orderId: String)
  fun cancelPayment()
}

Native Implementation (Your Code)

class PaymentHostApiImpl(
  private val activity: Activity
) : PaymentHostApi {

  override fun startPayment(orderId: String) {
    // Call native SDK (Juspay, Razorpay, etc.)
  }

  override fun cancelPayment() {
    // Handle cancellation
  }
}

Key Characteristics

Property HostApi
Call direction Flutter → Native
Implemented by Native
Used for Commands
Type safety ✅ Compile-time
JSON parsing ❌ None

2️⃣ FlutterApi Methods (Native → Flutter)

What are FlutterApi methods?

  • Defined in Dart
  • Implemented in Flutter
  • Called by native

Think of them as events or callbacks.

Use cases

  • Payment status updates
  • SDK lifecycle events
  • Sensor updates
  • Progress callbacks

Dart Definition

@FlutterApi()
abstract class PaymentFlutterApi {
  void onPaymentSuccess(String txnId);
  void onPaymentFailure(String reason);
}

Generated Native Class (Android – Kotlin)

class PaymentFlutterApi(
  private val binaryMessenger: BinaryMessenger
) {
  fun onPaymentSuccess(txnId: String) {}
  fun onPaymentFailure(reason: String) {}
}

Calling from Native

val flutterApi = PaymentFlutterApi(binaryMessenger)

flutterApi.onPaymentSuccess("TXN12345")
flutterApi.onPaymentFailure("Insufficient balance")

Flutter Implementation

class PaymentCallbacks extends PaymentFlutterApi {
  @override
  void onPaymentSuccess(String txnId) {
    // Update Bloc / Cubit / State
  }

  @override
  void onPaymentFailure(String reason) {
    // Show error UI
  }
}

Key Characteristics

Property FlutterApi
Call direction Native → Flutter
Implemented by Flutter
Used for Events
Real-time updates
State friendly

Visual Call Flow

Image

Flutter UI
   │
   │  HostApi (command)
   ▼
Native SDK
   │
   │  FlutterApi (event)
   ▼
Flutter StateUI rebuild

Async Methods in Pigeon

Pigeon supports async operations using Future in Dart.


Dart

@HostApi()
abstract class DeviceApi {
  Future<String> getDeviceId();
}

Android (Kotlin)

override fun getDeviceId(result: Result<String>) {
  try {
    result.success("ANDROID-DEVICE-001")
  } catch (e: Exception) {
    result.error(e)
  }
}

iOS (Swift)

func getDeviceId(completion: @escaping (Result<String, Error>) -> Void) {
  completion(.success("IOS-DEVICE-001"))
}

Common Real-World Pattern (Payments Example)

HostApi (Flutter → Native)

void initiatePayment(Map<String, String> payload);
void exitSdk();

FlutterApi (Native → Flutter)

void onTransactionSuccess(String txnId);
void onTransactionFailure(String error);
void onSdkClosed();

This pattern is used heavily in:

  • Juspay
  • Razorpay
  • Paytm
  • PhonePe

Why Pigeon is Better Than MethodChannel

Feature MethodChannel Pigeon
Type safety
Compile-time errors
JSON parsing Required None
Refactoring safety
Large SDK support Painful Clean

Mental Model to Remember

@HostApi     = Commands (Flutter → Native)
@FlutterApi  = Events   (Native → Flutter)

If you understand this, you understand Pigeon.


What Pigeon Does NOT Do

  • ❌ Render UI
  • ❌ Manage state
  • ❌ Replace Bloc / Cubit / Streams
  • ❌ Act as a real-time engine

It only guarantees safe communication.


Conclusion

Pigeon is not magic—but it removes an entire class of bugs from Flutter-native integration.

If your app:

  • Uses native SDKs
  • Handles real-time callbacks
  • Needs stability at scale

👉 Pigeon is the correct solution.

Post a Comment

Previous Post Next Post

Subscribe Us


Get tutorials, Flutter news and other exclusive content delivered to your inbox. Join 1000+ growth-oriented Flutter developers subscribed to the newsletter

100% value, 0% spam. Unsubscribe anytime