美文网首页Android开发经验谈
聊聊Flutter Platform SDK

聊聊Flutter Platform SDK

作者: e240c12aa0ad | 来源:发表于2020-05-11 13:57 被阅读0次

    前言

    从Flutter的架构图中可以看出,Flutter Platform SDK处于整个Flutter框架的上层,连接了Java与Dart代码。那么作为“最上层”的它,到底扮演了哪些角色,以及是如何扮演好这些角色的呢?Google工程师用一个封装好的flutter.jar包"show me the answer"。

    Platform SDK 的角色扮演

    通过对Platform SDK(以下简称 Platform)源码的阅读,可以大致将它分成三个角色:Creator(创建者),Transmitter(传递者),Registrant(注册者)。

    Creator

    创建者

    FlutterMain

    时序图
    image

    <figcaption style="margin: 10px 0px 0px; padding: 0px; max-width: 100%; box-sizing: border-box; word-wrap: break-word !important; font-size: 0.7em; color: rgb(153, 153, 153); line-height: inherit; text-align: center;">flutter_seq</figcaption>

    FlutterMain担任着flutter的初始化工作,在被Application的onCreate调起后

    • initConfig

      必须的配置文件名称和路径

    • 通过命令行 flutter build aot生成的文件

      名称 内容
      isolate_snapshot_instr 应用程序指令段
      isolate_snapshot_data 应用程序数据段
      vm_snapshot_instr VM 虚拟机指令段
      vm_snapshot_data VM 虚拟机数据段

      注:详细含义参见官方说明

    • 路径信息

      flutter_assets等文件的路径信息

    • initAot

    1. 初始化标记位:snapshot文件集成的方式。

    2. sIsPrecompiledAsSharedLibrary 代表的是把所有的snapshot文件打包成一个动态库(一种类似ios的集成方式)。

    3. 禁止同时采用两种集成方式。

    • initResource
    1. 创建了一个ResourceExtractor 对象,他是Resource文件的搬运工

    2. 通过ResourceExtractor 对象的addResource方法初始化需要搬运的文件

    3. ResourceExtractor启动异步任务把asset下面的文件搬运到DataDir的flutter目录下面

    FlutterActivityDelegate

    WhatDelegate
    //FlutterActivity.java......private final FlutterActivityEvents eventDelegate;private final Provider viewProvider;private final PluginRegistry pluginRegistry;   private final FlutterActivityDelegate delegate = new FlutterActivityDelegate(this, this);......public FlutterActivity() {        this.eventDelegate = this.delegate;        this.viewProvider = this.delegate;        this.pluginRegistry = this.delegate;    }......
    

    我们可以从上面FlutterActivity的构造函数中看出Delegate到底代理了哪些职责

    • FlutterActivityEvents:将Activity生命周期的具体处理逻辑传递给FlutterView

    • Provider:在onCreate中创建的FlutterView,通过实现Provider的接口暴露出来

    • PluginRegistry:插件信息的注册与查询传递给FlutterView

      从上面看来,其实FlutterActivityDelegate直接交互的对象就是FlutterView,通过这样的设计,提高了每一个类的内聚性

    image

    <figcaption style="margin: 10px 0px 0px; padding: 0px; max-width: 100%; box-sizing: border-box; word-wrap: break-word !important; font-size: 0.7em; color: rgb(153, 153, 153); line-height: inherit; text-align: center;">flutter内聚</figcaption>

    FlutterView

    可以先简单的把FlutterView看成是负责显示的,而把后面的FlutterNativeView看成是负责通信的。

    • 解偶系统控件

      首先我们可以看到FlutterView是继承自SurfaceView的,提到SurfaceView我们肯定会想到“挖洞”,“双缓冲”这些词,也正是因为这些特性FlutterView可以很好的把UI渲染工作交给Flutter( 后者通过dart->组装LayerTree->Skia完成绘制 )。

    image

    <figcaption style="margin: 10px 0px 0px; padding: 0px; max-width: 100%; box-sizing: border-box; word-wrap: break-word !important; font-size: 0.7em; color: rgb(153, 153, 153); line-height: inherit; text-align: center;">1655b109f83bea9b</figcaption>

    • 传递状态消息给Dart UI

      这些消息大致可以将它们分成七个模块,两大类

    1. 通过反射原生系统的api进行数据通讯

      多语言模块、系统信息和用户设置

    2. 将数据打包成特殊格式以消息的形式和使用Dart编写的flutter控件交互

      生命周期、按键消息、路由导航和平台插件

    FlutterNativeView

    可以先简单的把FlutterNativeView看成是负责通信的。它在系统层面上实现了BinaryMessenger接口 [这在下文Transmitter中详细介绍]。

    Transmitter

    传递者

    消息渠道

    • Flutter针对不同的应用场景封装了3类Channel
    1. MethodChannel:调用方法

    2. BasicMessageChannel:自定义结构信息

    3. EventChannel:事件的通知

    • 3类Channel拥有相似的结构类型
    1. 信使BinaryMessenger:我们自己创建的channel一般就是FlutterNativeView

    2. channel 名:channel的key值,不可重复

    3. MethodCodec /MessageCodec 解码器: 针对不同的channle解码二进制应答数据

    image

    <figcaption style="margin: 10px 0px 0px; padding: 0px; max-width: 100%; box-sizing: border-box; word-wrap: break-word !important; font-size: 0.7em; color: rgb(153, 153, 153); line-height: inherit; text-align: center;">channel</figcaption>

    消息编解码

    标准平台通道使用一个标准的消息编解码器。简单的JSON类值(如布尔值)的高效二进制序列化,数字、字符串、字节缓冲区以及这些列表和映射。(查看细节 StandardMessageCodec)。这些值的序列化和反序列化在消息发送和接收值时自动发生。(对应的数据转化关系如下)

    image

    <figcaption style="margin: 10px 0px 0px; padding: 0px; max-width: 100%; box-sizing: border-box; word-wrap: break-word !important; font-size: 0.7em; color: rgb(153, 153, 153); line-height: inherit; text-align: center;">解码</figcaption>

    传递流程

    通过Flutter Engine的数据转换,使得Dart和Android之间可以进行通信

    image

    <figcaption style="margin: 10px 0px 0px; padding: 0px; max-width: 100%; box-sizing: border-box; word-wrap: break-word !important; font-size: 0.7em; color: rgb(153, 153, 153); line-height: inherit; text-align: center;">channel流程图</figcaption>

    Registrant

    注册者

    情境转换

    首先这里有三个形似得英文单词registry, registrar and registrant分别对应注册局,注册商和注册人。把它们翻译到现实的生活场景中的角色其实是一个“注册人通过注册商,更新注册信息后,注册商把信息传递给注册局进行保存”的过程。下面我们把这个过程再翻译回代码:

    首先我们新建一个plugin插件,作为说明的对象:

    // 实现 PluginRegistry.ActivityResultListenerpublic class FlutterMusicPlugin implements MethodCallHandler, PluginRegistry.ActivityResultListener {    ...    public static void registerWith(Registrar registrar) {        //传入Activity        final FlutterMusicPlugin plugin = new FlutterMusicPlugin(registrar.activity());        ...        // 注册ActivityResult回调        registrar.addActivityResultListener(plugin);    }    @Override    public void onMethodCall(MethodCall call, Result result) {           ...    }    @Override    public boolean onActivityResult(int requestCode, int resultCode, Intent data) {           ...        return false;    }}
    

    同时在GeneratedPluginRegistrant类中会自动生成

    public final class GeneratedPluginRegistrant {  public static void registerWith(PluginRegistry registry) {    if (alreadyRegisteredWith(registry)) {      return;    } FlutterMusicPlugin.registerWith(registry.registrarFor("com.plugin.FlutterMusicPlugin"));  }  private static boolean alreadyRegisteredWith(PluginRegistry registry) {    final String key = GeneratedPluginRegistrant.class.getCanonicalName();    if (registry.hasPlugin(key)) {      return true;    }    registry.registrarFor(key);    return false;  }}
    

    注册人

    它对应的是代码中的GeneratedPluginRegistrant类

    • 发起注册

      GeneratedPluginRegistrant类中的

      FlutterMusicPlugin.registerWith(registry.registrarFor("com.plugin.FlutterMusicPlugin"));//即为发起注册点
      
    • 通过注册商更新注册

      FlutterMusicPlugin类中的

      registrar.addActivityResultListener(plugin);//即为通过注册商更新了需要Activity回调的信息
      
    • 同步给注册局

      sdk中的FlutterRegistrar类

      FlutterPluginRegistry.this.mActivityResultListeners.add(listener);//即为把信息同步给了注册局
      

    注册商

    它对应的是代码中的FlutterPluginRegistry内部类FlutterRegistrar。

    不看不知道,"注册商"其实给我们提供了很多功能,比如获取activity,viewDestory的生命周期的回调,获取surfaceTexture等等,真是一个能力强大的"注册商"。

            Activity activity();//返回 Host app的Activity        Context context();//返回 Application Context.        Context activeContext();//返回 活动Context        //返回 BinaryMessenger 主要用来注册Platform channels        BinaryMessenger messenger();        //返回 TextureRegistry,从里面可以拿到SurfaceTexture         TextureRegistry textures();        //返回 当前Host app创建的FlutterView        FlutterView view();        //返回Asset对应的文件路径        String lookupKeyForAsset(String var1);        //返回Asset对应的文件路径        String lookupKeyForAsset(String var1, String var2);        //插件对外发布的一个"值"        PluginRegistry.Registrar publish(Object var1);        //注册权限相关的回调        PluginRegistry.Registrar addRequestPermissionsResultListener(PluginRegistry.RequestPermissionsResultListener var1);        //注册ActivityResult回调        PluginRegistry.Registrar addActivityResultListener(PluginRegistry.ActivityResultListener var1);        //注册NewIntent回调        PluginRegistry.Registrar addNewIntentListener(PluginRegistry.NewIntentListener var1);        //注册UserLeaveHint回调        PluginRegistry.Registrar addUserLeaveHintListener(PluginRegistry.UserLeaveHintListener var1);        //注册View销毁回调        PluginRegistry.Registrar addViewDestroyListener(PluginRegistry.ViewDestroyListener var1);
    

    注册局

    它对应的是代码中的FlutterPluginRegistry

    image

    <figcaption style="margin: 10px 0px 0px; padding: 0px; max-width: 100%; box-sizing: border-box; word-wrap: break-word !important; font-size: 0.7em; color: rgb(153, 153, 153); line-height: inherit; text-align: center;">pluginregister</figcaption>

    从成员变量可以看出FlutterPluginRegistry主要维护两类信息:

    • 注册插件唯一标识信息汇总

    • FlutterRegistrar所开放的那些功能(比如:addActivityResultListener)的信息汇总

    转自:https://mp.weixin.qq.com/s/AxupxgiywFHgLBp_fVOdNw

    相关文章

      网友评论

        本文标题:聊聊Flutter Platform SDK

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