内容简介: 从Flutter的架构图中可以看出,Flutter Platform SDK处于整个Flutter框架的上层,连接了Java与Dart代码。那么作为“最上层”的它,到底扮演了哪些角色,以及是如何扮演好这些角色的呢?Google工程师用一个封装好的flutter.jar包"show me the answer"。 通过对Platform SDK(以下简称 Platform)源码的阅读,可以大致将它分成三个角色:Creator(创建者),Transmitter(传递者),Registrant(注册人)。创
从Flutter的架构图中可以看出,Flutter Platform SDK处于整个Flutter框架的上层,连接了 Java 与Dart代码。那么作为“最上层”的它,到底扮演了哪些角色,以及是如何扮演好这些角色的呢?Google工程师用一个封装好的flutter.jar包"show me the answer"。
Platform SDK 的角色扮演
通过对Platform SDK(以下简称 Platform)源码的阅读,可以大致将它分成三个角色:Creator(创建者),Transmitter(传递者),Registrant(注册人)。
Creator
创建者
FlutterMain
时序图
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
- 初始化标记位:snapshot文件集成的方式。
- sIsPrecompiledAsSharedLibrary 代表的是把所有的snapshot文件打包成一个动态库(一种类似ios的集成方式)。
- 禁止同时采用两种集成方式。
-
initResource
- 创建了一个ResourceExtractor 对象,他是Resource文件的搬运工
- 通过ResourceExtractor 对象的addResource方法初始化需要搬运的文件
- 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,通过这样的设计,提高了每一个类的内聚性
FlutterView
可以先简单的把FlutterView看成是负责显示的,而把后面的FlutterNativeView看成是负责通信的。
-
解偶系统控件
首先我们可以看到FlutterView是继承自SurfaceView的,提到SurfaceView我们肯定会想到“挖洞”,“双缓冲”这些词,也正是因为这些特性FlutterView可以很好的把UI渲染工作交给Flutter( 后者通过dart->组装LayerTree->Skia完成绘制 )。
-
传递状态消息给Dart UI
这些消息大致可以将它们分成七个模块,两大类
-
通过反射原生系统的api进行数据通讯
多语言模块、系统信息和用户设置
-
将数据打包成特殊格式以消息的形式和使用Dart编写的flutter控件交互
生命周期、按键消息、路由导航和平台插件
-
FlutterNativeView
可以先简单的把FlutterNativeView看成是负责通信的。它在系统层面上实现了BinaryMessenger接口 [这在下文 Transmitter 中详细介绍]。
Transmitter
传递者
消息渠道
-
Flutter针对不同的应用场景封装了3类Channel
- MethodChannel:调用方法
- BasicMessageChannel:自定义结构信息
- EventChannel:事件的通知
-
3类Channel拥有相似的结构类型
- 信使BinaryMessenger:我们自己创建的channel一般就是FlutterNativeView
- channel 名:channel的key值,不可重复
- MethodCodec /MessageCodec 解码器: 针对不同的channle解码二进制应答数据
消息编解码
标准平台通道使用一个标准的消息编解码器。简单的JSON类值(如布尔值)的高效二进制序列化,数字、字符串、字节缓冲区以及这些列表和映射。(查看细节 StandardMessageCodec
)。这些值的序列化和反序列化在消息发送和接收值时自动发生。(对应的数据转化关系如下)
传递流程
通过Flutter Engine的数据转换,使得Dart和Android之间可以进行通信
Registrant
注册人
情境转换
首先这里有三个形似得英文单词registry, registrar and registrant分别对应注册局,注册商和注册人。把它们翻译到现实的生活场景中的角色其实是一个“注册人通过注册商,更新注册信息后,注册商把信息传递给注册局进行保存”的过程。下面我们把这个过程再翻译回代码:
首先我们新建一个plugin插件,作为说明的对象:
// 实现 PluginRegistry.ActivityResultListener public 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); 复制代码
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Java编程的逻辑
马俊昌 / 机械工业出版社 / 2018-1-1 / 99
Java专家撰写,力求透彻讲解每个知识点,逐步建立编程知识图谱。本书以Java语言为例,由基础概念入手,到背后实现原理与逻辑,再到应用实践,融会贯通。 全书共六大部分,其要点如下。 第一部分(第1~2章)讲解计算机程序的基本执行流程与元素,以及数据背后的二进制表示,帮读者掌握编程的基本概念。 第二部分(第3~7章)讲解面向对象的编程原理与逻辑,涉及类、继承与多态、接口与抽象类、异......一起来看看 《Java编程的逻辑》 这本书的介绍吧!