Chuyển đến nội dung chính

第 15 課:平台通路與本機集成

方法通道、事件通道。從 Flutter (iOS/Android) 呼叫本機程式碼。鴿子代碼生成。用於 C/C++ 函式庫的 FFI。插件開發。

💻 程式設計 — 第 15 課 第 15 課:平台通路與原生 整合

Flutter 和 Dart:從基礎到高級

第 4 部分:進階 UI 和功能

亞洲開發網

1.方法通道

// Dart side
class BatteryService {
  static const _channel = MethodChannel('com.example.app/battery');

  Future<int> getBatteryLevel() async {
    final level = await _channel.invokeMethod<int>('getBatteryLevel');
    return level ?? -1;
  }
}
// Android — MainActivity.kt
class MainActivity : FlutterActivity() {
    private val CHANNEL = "com.example.app/battery"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
            .setMethodCallHandler { call, result ->
                when (call.method) {
                    "getBatteryLevel" -> {
                        val batteryManager = getSystemService(BATTERY_SERVICE) as BatteryManager
                        val level = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
                        result.success(level)
                    }
                    else -> result.notImplemented()
                }
            }
    }
}
// iOS — AppDelegate.swift
@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.app/battery", binaryMessenger: controller.binaryMessenger)

        channel.setMethodCallHandler { (call, result) in
            if call.method == "getBatteryLevel" {
                UIDevice.current.isBatteryMonitoringEnabled = true
                let level = Int(UIDevice.current.batteryLevel * 100)
                result(level)
            } else {
                result(FlutterMethodNotImplemented)
            }
        }

        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
}

2. EventChannel-來自 Native 的串流

// Dart side — lắng nghe sensor
class AccelerometerService {
  static const _channel = EventChannel('com.example.app/accelerometer');

  Stream<AccelerometerData> get stream {
    return _channel.receiveBroadcastStream().map((event) {
      final data = event as Map;
      return AccelerometerData(
        x: data['x'] as double,
        y: data['y'] as double,
        z: data['z'] as double,
      );
    });
  }
}

3. Pigeon — 類型安全的代碼生成

// pigeons/messages.dart
import 'package:pigeon/pigeon.dart';

class SearchRequest {
  String? query;
  int? limit;
}

class SearchResponse {
  List<String?>? results;
}

@HostApi()
abstract class SearchApi {
  SearchResponse search(SearchRequest request);
}
# Generate
dart run pigeon --input pigeons/messages.dart \
    --dart_out lib/src/generated/messages.g.dart \
    --kotlin_out android/app/src/main/kotlin/Messages.g.kt \
    --swift_out ios/Runner/Messages.g.swift

4. 達特FFI

import 'dart:ffi';

typedef NativeAdd = Int32 Function(Int32, Int32);
typedef DartAdd = int Function(int, int);

final dylib = DynamicLibrary.open('libnative.so');

final add = dylib.lookupFunction<NativeAdd, DartAdd>('add');

void main() {
  print(add(3, 5)); // 8
}

下一篇: 推播通知和後台任務。