在Dart和本机代码之间的Flutter中创建桥梁

如何在Dart和本机代码之间的Flutter中建立桥梁

Flutter允许我们调用Android上的Java或Kotlin代码以及iOS上的Objective C或Swift代码可用的平台特定的API。

Flutter的特定于平台的API可用于消息传递。

从Flutter应用程序中,我们必须通过平台通道将消息发送到该应用程序的iOS或Android部分上的主机。 主机在平台通道上侦听并接收消息。 然后,它将使用本机编程语言使用任何特定于平台的API,并将响应发送回应用程序的Flutter部分。

架构概述

消息使用平台通道在Flutter Code(UI)和主机(平台)之间传递。 消息和响应异步传递,并且用户界面保持响应。

在Dart端,使用MethodChannel(API)我们发送一条与方法调用相对应的消息。 在Android上,MethodChannel Android(API)和iOS上,FlutterMessageChannel(API)用于接收方法调用和发送回结果。 这些类使我们能够使用非常简单的代码来开发平台插件。

如果需要,方法调用也可以反向发送,而Android / IOS平台充当Dart中实现的客户端和方法。

平台渠道支持的数据类型

标准平台通道使用标准消息编解码器,该消息编解码器支持对简单的类JSON值(布尔值,数字,字符串,字节缓冲区,列表和映射)进行有效的二进制序列化。 当我们发送和接收值时,这些值与消息之间的序列化和反序列化会自动发生。

创建调用iOS和Android代码的Flutter应用

现在,我们将创建一个带有方法调用的flutter应用程序,该方法调用将分别在Android(Java)和iOS(Objective C)中实现。

1.创建一个新的应用程序项目

在终端运行中:

flutter创建flutter_to_native

默认情况下,Flutter支持在Java和iOS中使用Objective C编写Android代码。如果要使用Kotlin和Swift,请使用以下命令创建项目。

flutter create -i swift -a kotlin flutter_to_native

2.创建平台频道

通道的客户端和主机端通过在通道构造函数中传递的通道名称连接。 单个应用中使用的所有频道名称必须唯一。 在我们的示例中,我们正在创建频道名称flutter.native / helper

class _MyHomePageState extends State<MyHomePage> { static const platform = const MethodChannel( 'flutter.native/helper' );
3.在平台通道上调用方法

在方法通道上调用方法,并通过String标识符指定要调用的具体方法。 在下面的代码中,它是helloFromNativeCode

String response = "" ; try { final String result = await platform .invokeMethod( 'helloFromNativeCode' ); response = result; } on PlatformException catch (e) { response = "Failed to Invoke: ' ${e. message } '." ; }

使用返回的响应来更新setState中的用户界面状态。

setState(() { _responseFromNativeCode = response; });
4.使用Java在Android中创建方法实现

在Android Studio中,打开Flutter应用,然后选择其中的android文件夹。 打开文件MainActivity.java

现在,我们必须创建一个与在Flutter App中创建的名称相同的MethodChannel。

public class MainActivity extends FlutterActivity { private static final String CHANNEL = "flutter.native/helper" ;

我们必须在onCreate方法中创建MethodCallHandler

new MethodChannel(getFlutterView(), CHANNEL ).setMethodCallHandler( new MethodChannel.MethodCallHandler() { @Override public void onMethodCall(MethodCall call, MethodChannel.Result result) { if (call. method .equals( "helloFromNativeCode" )) { String greetings = helloFromNativeCode(); result.success(greetings); } }});
5.使用Objective C在iOS中创建方法实现

在Xcode中打开Flutter应用的文件AppDelegate.m。 现在,我们必须创建一个FlutterMethodChannel,其名称与在Flutter App中创建的名称相同。

FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController; FlutterMethodChannel* nativeChannel = [FlutterMethodChannel methodChannelWithName:@ "flutter.native/helper" binaryMessenger:controller];

创建方法调用处理程序

[nativeChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { if ([@ "helloFromNativeCode" isEqualToString:call.method]) { NSString *strNative = [weakSelf helloFromNativeCode]; result(strNative); } else { result(FlutterMethodNotImplemented); } }];

完整的代码

Android本机代码
import android.os.Bundle; import io.flutter.app.FlutterActivity; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugins.GeneratedPluginRegistrant; public class MainActivity extends FlutterActivity { private static final String CHANNEL = "flutter.native/helper" ; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); GeneratedPluginRegistrant. registerWith ( this ); new MethodChannel(getFlutterView(), CHANNEL ).setMethodCallHandler( new MethodChannel.MethodCallHandler() { @Override public void onMethodCall(MethodCall call, MethodChannel.Result result) { if (call. method .equals( "helloFromNativeCode" )) { String greetings = helloFromNativeCode(); result.success(greetings); } }}); } public class MainActivity extends FlutterActivity { private static final String CHANNEL = "flutter.native/helper" ; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); GeneratedPluginRegistrant. registerWith ( this ); new MethodChannel(getFlutterView(), CHANNEL ).setMethodCallHandler( new MethodChannel.MethodCallHandler() { @Override public void onMethodCall(MethodCall call, MethodChannel.Result result) { if (call. method .equals( "helloFromNativeCode" )) { String greetings = helloFromNativeCode(); result.success(greetings); } }}); } private String helloFromNativeCode() { return "Hello from Native Android Code" ; } } private String helloFromNativeCode() { return "Hello from Native Android Code" ; } }
iOS本机代码
#include "AppDelegate.h" #include "GeneratedPluginRegistrant.h" @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController; FlutterMethodChannel* nativeChannel = [FlutterMethodChannel methodChannelWithName:@ "flutter.native/helper" binaryMessenger:controller]; __weak typeof(self) weakSelf = self; [nativeChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { if ([@ "helloFromNativeCode" isEqualToString:call.method]) { NSString *strNative = [weakSelf helloFromNativeCode]; result(strNative); } else { result(FlutterMethodNotImplemented); } }]; [GeneratedPluginRegistrant registerWithRegistry:self]; return [ super application:application didFinishLaunchingWithOptions:launchOptions]; } - (NSString *)helloFromNativeCode { return @ "Hello From Native IOS Code" ; } @end
颤动代码
import 'package:flutter/material.dart' ; import 'dart:async' ; import 'package:flutter/services.dart' ; void main() => runApp( new MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( home: new HomePage(), ); } } class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: const Text( 'Native Code from Dart' ), ), body: new MyHomePage(), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this . title }) : super (key: key); final String title ; @override _MyHomePageState createState() => new _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { static const platform = const MethodChannel( 'flutter.native/helper' ); String _responseFromNativeCode = 'Waiting for Response...' ; Future< void > responseFromNativeCode() async { String response = "" ; try { final String result = await platform .invokeMethod( 'helloFromNativeCode' ); response = result; } on PlatformException catch (e) { response = "Failed to Invoke: ' ${e. message } '." ; } setState(() { _responseFromNativeCode = response; }); } @override Widget build(BuildContext context) { return Material( child: Center( child: Column( mainAxisAlignment: MainAxisAlignment. spaceEvenly , children: [ RaisedButton( child: Text( 'Call Native Method' ), onPressed: responseFromNativeCode, ), Text( _responseFromNativeCode ), ], ), ), ); } }

结果

在Android和iOS设备上运行代码。 单击按钮“调用本机方法”

最后结果

感谢 Atul Sharma 的文章。 如果您喜欢这篇文章,请随时单击该鼓掌按钮👏,以帮助其他人找到它。

本文是与移动技术相关的系列文章的一部分。 如果您正在寻找移动应用程序开发团队,请通过 info@47billion.com 与我们联系

最初于 2019 年1月15日 47billion.com 发布

From: https://hackernoon.com/creating-a-bridge-in-flutter-between-dart-and-native-code-b667f4dc164a

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值