• Flutter-填平菜鸟和高手之间的沟壑


    Flutter-填平菜鸟和高手之间的沟壑

    准备写作中...

    1、Flutter-skia-影像,Flutter skia-图形渲染层、应用渲染层
    2、方法通道使用示例,用于演示如何使用方法通道实现与原生代码的交互
    需求:提示用户跳转到应用市场去评分
    在实际业务中,提示用户跳转到应用市场(iOS 为 App Store、Android 则为各类手机应用市场)去评分是一个高频需求,考虑到 Flutter 并未提供这样的接口,而跳转方式在 Android 和 iOS 上各不相同,因此我们需要分别在 Android 和 iOS 上实现这样的功能,并暴露给 Dart 相关的接口。
    我们先来看看作为客户端的 Flutter,怎样实现一次方法调用请求,实际上与调用一个 Dart 对象的方法完全一样。
    (1)首先,我们需要确定一个唯一的字符串标识符,来构造一个命名通道;
    (2)然后,在这个通道之上,Flutter 通过指定方法名“openAppMarket”来发起一次方法调用请求。
    (3)最后,因为方法调用过程是异步的,需要用非阻塞(或者注册回调)方式来等待原生代码给予响应。

    3、把发起方法调用请求的语句用 try-catch 包装起来,处理异常
    需要注意的是,与网络调用类似,方法调用请求有可能会失败(比如,Flutter 发起了原生代码不支持的 API 调用,或是调用过程出错等),因此我们需要把发起方法调用请求的语句用 try-catch 包装起来。

    //声明MethodChannel
    const platform = MethodChannel('samples.chenhang/utils');

    //处理按钮点击
    handleButtonClick() async {
    int result;
    //异常捕获
    try {
    //异步等待方法通道的调用结果
    result = await platform.invokeMethod('openAppMarket');
    } catch (e) {
    result = -1;
    }
    print("Result:$result");
    }

    4、分别在 Android 和 iOS 两个平台上完成对应的接口实现,在原生代码中完成方法调用的响应
    调用方的实现搞定了,接下来就需要在原生代码宿主中完成方法调用的响应实现了。由于我们需要适配 Android 和 iOS 两个平台,所以我们分别需要在两个平台上完成对应的接口实现。

    首先,我们来看看 Android 端的实现方式。
    (1)在上一小结最后我提到,在 Android 平台,方法调用的处理和响应是在 Flutter 应用的入口,也就是在 MainActivity 中的 FlutterView 里实现的,因此我们需要打开 Flutter 的 Android 宿主 App,找到 MainActivity.java 文件,并在其中添加相关的逻辑。
    A、用 AS 打开 Flutter 项目 flutter_app_top_tab_03
    B、然后,在 Flutter 项目 flutter_app_top_tab_03 中,右击该项目的 android 子项目选择用 Android 打开。如果直接在 Flutter 项目中编写安卓代码,会有许多红线报错,也没有安卓命令提示、无法用 Ctrl + Alt + L 进行代码格式化

    (2)调用方与响应方都是通过命名通道进行信息交互的,所以我们需要在 onCreate 方法中,创建一个与调用方 Flutter 所使用的通道名称一样的 MethodChannel,并在其中设置方法处理回调,响应 openAppMarket 方法,打开应用市场的 Intent。
    (3)同样地,考虑到打开应用市场的过程可能会出错,我们也需要增加 try-catch 来捕获可能的异常:

    r:FlutterProjectFlutterProject3526_native_methodandroidappsrcmainjavacomexample ative_methodMainActivity.java
    文件内容:
    package com.hangchen.native_method;

    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;
    import android.content.Intent;
    import android.net.Uri;
    import android.os.Bundle;
    public class MainActivity extends FlutterActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    GeneratedPluginRegistrant.registerWith(this);

    new MethodChannel(getFlutterView(), "samples.chenhang/navigation").setMethodCallHandler(
    new MethodChannel.MethodCallHandler() {
    @Override
    public void onMethodCall(MethodCall call, MethodChannel.Result result) {
    // Note: this method is invoked on the main thread.
    if(call.method.equals("openAppStore")) {
    try {
    Uri uri = Uri.parse("market://details?id=com.tencent.mm");
    Intent intent = new Intent(Intent.ACTION_VIEW, uri);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
    } catch (Exception e) {
    result.error("UNAVAILABLE", "没有安装应用市场", null);
    }
    }
    else {
    result.notImplemented();
    }
    }
    });
    }
    }


    5、在 Flutter 应用中通过调用 openAppMarket 方法,实现打开应用市场的功能,
    需要注意的是,在 Flutter 使用方法通道进行方法调用和原生代码返回处理结果的过程中,存在传输信息的序列化和反序列化。

    接下来,我们就可以在 Flutter 应用里,通过调用 openAppMarket 方法,实现打开不同操作系统提供的应用市场功能了。
    需要注意的是,在原生代码处理完毕后将处理结果返回给 Flutter 时,我们在 Dart、Android 和 iOS 分别用了三种数据类型:
    Android 端返回的是 java.lang.Integer、
    iOS 端返回的是 NSNumber、
    Dart 端接收到返回结果时又变成了 int 类型。
    这是为什么呢?这是因为在使用方法通道进行方法调用时,由于涉及到跨系统数据交互,Flutter 会使用 StandardMessageCodec 对通道中传输的信息进行类似 JSON 的二进制序列化,以标准化数据传输行为。这样在我们发送或者接收数据时,这些数据就会根据各自系统预定的规则自动进行序列化和反序列化。
    看到这里,你是不是对这样类似网络调用的方法通道技术有了更深刻的印象呢。对于上面提到的例子,类型为 java.lang.Integer 或 NSNumber 的返回值,先是被序列化成了一段二进制格式的数据在通道中传输,然后当该数据传递到 Flutter 后,又被反序列化成了 Dart 语言中的 int 类型的数据。
    关于 Android、iOS 和 Dart 平台间的常见数据类型转换,我总结成了下面一张表格,帮助你理解与记忆。你只要记住,像 null、布尔、整型、字符串、数组和字典这些基本类型,是可以在各个平台之间以平台定义的规则去混用的,就可以了。

  • 相关阅读:
    难以实践敏捷:估算
    使用AsyncEnumerator简化异步操作
    ESXi 入门配置
    学习模式,不如先了解问题
    我应该用哪种虚拟机?(一)
    在2003上实现Custom Task Pane
    我应该用哪种虚拟机?(终)
    我应该用哪种虚拟机?(二)
    正则表达式周二挑战赛 第十二周
    [译]Node中的ES6特性
  • 原文地址:https://www.cnblogs.com/ybmj/p/14437345.html
Copyright © 2020-2023  润新知