美文网首页
Flutter -- 与原生交互

Flutter -- 与原生交互

作者: jancywen | 来源:发表于2021-02-08 20:24 被阅读0次

为了解决调用原生系统底层能力以及相关代码库复用问题,Flutter 为开发者提供了一个轻量级的解决方案,即逻辑层的方法通道(Method Channel)机制。基于方法通道,我们可以将原生代码所拥有的能力,以接口形式暴露给 Dart,从而实现 Dart 代码与原生代码的交互,就像调用了一个普通的 Dart API 一样。

方法通道

一次典型的方法调用过程类似网络调用,由作为客户端的 Flutter,通过方法通道向作为服务端的原生代码宿主发送方法调用请求,原生代码宿主在监听到方法调用的消息后,调用平台相关的 API 来处理 Flutter 发起的请求,最后将处理完毕的结果通过方法通道回发至 Flutter。

下面来实现一次方法调用请求

首先,我们需要确定一个唯一的字符串标识符,来构造一个命名通道;然后,在这个通道之上,Flutter 通过指定方法名“ testChannel”来发起一次方法调用请求。
可以看到,这和我们平时调用一个 Dart 对象的方法完全一样。因为方法调用过程是异步的,所以我们需要使用非阻塞(或者注册回调)来等待原生代码给予响应。
需要注意的是,与网络调用类似,方法调用请求有可能会失败,因此我们需要把发起方法调用请求的语句用 try-catch 包装起来。

class _HomeMainPageState extends State<HomeMainPage> with AutomaticKeepAliveClientMixin {

  /// 保持状态
  @override
  bool get wantKeepAlive => true;

  String testStr;

  static const platform = MethodChannel("ESHOPCHANNEL");

  @override
  void initState() {
    super.initState();
    _testChannel();
  }

  _testChannel() async {
    var str;
    try {
      str = await platform.invokeMethod<String>('testChannel');
      setState(() {
        testStr = str;
      });
    } catch (e) {
      debugPrint(e.toString());
    }
    
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Scaffold(
      body: Center(child: Text(testStr ?? ""),),
    );
  }
}

iOS端处理

在入口方法内部创建一个FlutterMethodChannel,并添加一个处理方法。 确保与在Flutter客户端使用的通道名称相同。

// AppDelegate.swift
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        GeneratedPluginRegistrant.register(with: self)
        if let controller: FlutterViewController = window?.rootViewController as? FlutterViewController,
           let binaryMessager = controller as? FlutterBinaryMessenger {
            let batteryChannel = FlutterMethodChannel.init(name: channelName, binaryMessenger: binaryMessager)
            batteryChannel.setMethodCallHandler(MethodChannelManager.manager.methodCallHandler(call:result:))
        }
        
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
}

******************
// MethodChannelManager.swift
let channelName = "ESHOPCHANNEL"

class MethodChannelManager {
    // 单例
    static let manager = MethodChannelManager()
    private init(){}
    
    func methodCallHandler(call: FlutterMethodCall, result: FlutterResult) {
        guard let type = MethodChannelType(rawValue: call.method) else {
            result(FlutterMethodNotImplemented)
            return
        }
        switch type {
        case .test:
            testChannel(result: result)
        }
    }
    
    // test
    private func testChannel(result: FlutterResult) {
        result("test")
    }
}

enum MethodChannelType: String {
    case test = "testChannel"
}

参考:插件开发:实现iOS端 API

相关文章

网友评论

      本文标题:Flutter -- 与原生交互

      本文链接:https://www.haomeiwen.com/subject/svsbtltx.html