滴滴DoKit For Flutter正式开源,还是原来的“味道”

滴滴DoKit Android核心原理揭秘之函数耗时 技术背景 在日常的开发过程中,App的性能和用户体验一直是我们关注的重点,尤其是对于大公司来说每天的日活都是千万或者上亿的量级。操作过程中的不流畅和卡顿将严重影响用户的体验,甚至可能面临卸载导致用户流失。在拉新成本居高不下的现阶段,每一个用户的流失对于我们来说都是直接的损失。所以想要留住用户就必须提升用户体验,那么流畅顺滑操作过程无卡顿就是我们最基本也是重要的一环。但是随着现在移动端App的业务功能越来越复杂,随之带来的代码量剧增。在几十万行的代码中难免会出现效率低下或者不符合开发规范的代码存在,传统的代 阅读详情

社区的小伙伴们,大家好啊,艰难的2020已经过去,随着2021的到来,在新的一年里希望大家都能够需求不变更、准点上下班、代码0 Bug。同时也给大家准备了一份特殊的“新年礼物”,没错它就是DoKit For Flutter,它来啦,它带着熟悉的配方来啦。接下来就让我们揭开它神秘的面纱吧。

背景

Flutter是Google开源的跨端技术框架。凭借其区别于RN/Weex的自渲染模式,在社区里引起了广泛关注,不管是终端还是前端的小伙伴都趋之若鹜,大有一统大前端江湖的气势。而国内大厂如闲鱼、字节、美团等,也都在其核心业务上完成了落地。

滴滴作为国内最大的出行平台,早在两年前就有多个内部团队开始在Flutter领域进行尝试。但是在开发过程中,我们遇到了很多调试性问题,如日志、帧率、抓包等。为了解决这些开发测试过程中遇到的各类问题,我们联合滴滴代驾和货运团队,把平时工作过程中沉淀下来的效率工具进行业务剥离和脱敏,并最终打造出DoKit For Flutter,在服务内部业务的同时,也为社区贡献一份力量,这也是滴滴的开源精神。

介绍

DoKit For Flutter是一个DoKit针对Flutter环境的产研工具包,内部集成了各种丰富的小工具,UI、网络、内存、监控等等。DoKit始终站在用户的角度,为用户提供最便利的产研工具。

Github地址

Pub仓库地址

操作文档

 

 

那么接下来就让我来列举一下DoKit For Flutter的功能以及核心实现。

工具详解

基本信息

基本信息模块会展示当前dart虚拟机进程、CPU、Flutter版本信息、当前App包名和dart工程构建版本信息;

 

 

VM信息通过VMService获取。Flutter版本实际上是通过Devtools服务注入的"flutterVersion"方法获取到的,在flutter attach后,本地会起一个websocket服务,连接VMService并注入flutterVersion和其余方法(HotReload、HotRestart等),通过VMService调用flutterVersion方法,会从本地flutter sdk目录下解析version文件返回版本号。

路由信息

 

 

在Flutter中,每个页面对应一个Route,通过Navigator管理Route。Navigator内部会包含一个Overlay Widget,每个Route最终都转化成一个_OverlayEntryWidget添加到Overlay上。这个地方可以把Overlay理解为Android中的FrameLayout,内部的View上下叠加。每打开一个新的Route,都相当于往FrameLayout添加一个新的子View。Navigator会存在嵌套的情况,即Route所创建的页面本身也包含一个Navigator,比如App的根Widget是MaterialApp(自带Navigator),Route页面也用MaterialApp包裹,就会形成Navigator嵌套的情况。还是以FrameLayout来理解,这也就相当于嵌套的FrameLayout。 路由信息功能会打印出当前栈顶页面所处的Route信息,如果存在Navigator嵌套的情况,也会向上遍历打印出每层Navigator的信息。具体的实现方式是,先获取当前根app根Element,可以使用WidgetsBinding.instance.renderViewElement作为根Element,再通过递归调用element的visitChildElements方法,向下遍历整棵树找到最后一个RenderObejctElement,该RenderObejctElement即为当前显示的页面上的元素。然后使用ModalRoute.of(element)方法即可获取到当前页面的路由信息。

至于嵌套的路由信息,则可以通过找到的RenderObejctElement的findAncestorStateOfType方法,反向向上递归遍历,获得所处的Navigator的NavigatorState,再调用ModalRoute.of(navigatorState.context),如果返回不为空则表示存在嵌套。

方法通道

 

 

Flutter的Method Channel调用最终都会经过ServiceBinding.instance._defaultBinaryMessenger这个对象,类型为BinaryMessenger,由于这个对象是个私有对象,无法动态进行修改。不过查看ServiceBinding的源码可以发现这个对象是通过ServiceBinding.createBinaryMessenger方法创建的,通过使用flutter的mixins,可以实现对该方法的重写。 我们知道,ServiceBinding实际也是通过mixins在WidgetsFlutterBinding.ensureInitialized方法中一起被初始化的,所以只要在WidgetsFlutterBinding这个类额外mixin一个继承于ServiceBinding并且重写了createBinaryMessenger方法的类,就能实现对ServiceBinding中createBinaryMessenger的覆盖,代码如下:

class DoKitWidgetsFlutterBinding extends WidgetsFlutterBinding
    with DoKitServicesBinding {
  static WidgetsBinding ensureInitialized() {
    if (WidgetsBinding.instance == null) DoKitWidgetsFlutterBinding();
    return WidgetsBinding.instance;
  }
}

mixin DoKitServicesBinding on BindingBase, ServicesBinding {
  @override
  BinaryMessenger createBinaryMessenger() {
    return DoKitBinaryMessenger(super.createBinaryMessenger());
  }
}

接下去把runApp的入口调用改成如下,就能实现BinaryMessenger的替换 static void _runWrapperApp(DoKitApp wrapper) { DoKitWidgetsFlutterBinding.ensureInitialized() ..scheduleAttachRootWidget(wrapper) ..scheduleWarmUpFrame(); } 至于Method Channel具体信息的捕获,只要hook住BinaryMessenger.handlePlatformMessage和BinaryMessenger.send两个方法就行了,具体可看DoKitBinaryMessenger这个类

控件检查

 

 

和路由功能类似,通过从根element向下遍历,在遍历过程中记录和选中的View有交集的所有RendereObjectElement,并且记录用以标志当前页面的RendereObjectElement,获取它的Route信息。遍历完成后,遍历记录下来的RendereObjectElement,过滤掉Route信息和当前页面不一致的,这些Element属于被遮盖住的页面。然后通过比对RendereObjectElement和选中View的交叉区域面积占RendereObjectElement面积的比例,占比最大的为当前选中的组件。 在Debug模式下可以获取选中组件在工程中的代码位置,将WidgetInspectorService.instance.selection.current赋值为选中element的renderObject,再调用WidgetInspectorService.instance.getSelectedSummaryWidget方法,会返回一个json字符串,解析这个字符串就能获取源码文件名、行列信息等。

日志查看

 

 

日志查看功能比较简单,只要使用runZoned方法替代runApp,传入zoneSpecification,就能为日志输出设置一个代理函数,在这个代理函数内进行日志捕获,同时,还可以为onError设置一个代理函数,在这里将捕获的异常也会传入到日志当中。

帧率

 

 

使用WidgetsBinding.instance.addTimingsCallback可以统计帧率信息,在每帧渲染完成时会触发回调,包含该帧渲染的信息。

内存

 

 

同VM信息,使用VMService可以获取到内存详细使用信息。

网络请求

 

 

Flutter自带的网络请求通过HttpClient类发送,只要hook住HttpClient的创建就可以hook整个网络请求的过程。查看HttpClient的构造函数可以发现,如果存在HttpOverrides,就会使用HttpOverrids来创建HttpClient

factory HttpClient({SecurityContext? context}) {
  HttpOverrides? overrides = HttpOverrides.current;
  if (overrides == null) {
    return new _HttpClient(context);
  }
  return overrides.createHttpClient(context);
}
所以这里重写了一个HttpOverrids
class DoKitHttpOverrides extends HttpOverrides {
  final HttpOverrides origin;

  DoKitHttpOverrides(this.origin);

  @override
  HttpClient createHttpClient(SecurityContext context) {
    if (origin != null) {
      return DoKitHttpClient(origin.createHttpClient(context));
    }
    // 置空,防止递归调用,使得_HttpClient可以被初始化
    HttpOverrides.global = null;
    HttpClient client = DoKitHttpClient(new HttpClient(context: context));
    // 创建完成后继续置回DoKitHttpOverrides
    HttpOverrides.global = this;
    return client;
  }
}

替换HttpOverrides

HttpOverrides origin = HttpOverrides.current;
HttpOverrides.global = new DoKitHttpOverrides(origin);

hook住HttpClient方法后,对于请求和返回结果的hook过程就和Android中的HttpUrlConnection类似了,具体可以看DoKitHttpClient、DoKitHttpClientRequest、DoKitHttpClientResponse三个类。

版本API兼容

Flutter版本更新还是比较快的,每一个大版本更新都会带来一些API的变更,目前DoKit的方案需要重写一些framework层的类,在兼容多版本时就会有一些问题。以上面的BinaryMessager为例,1.17版本只有四个方法,用来hook的DoKitBinaryMessager是这么写的

class DoKitBinaryMessenger extends BinaryMessenger {
  final MethodCodec codec = const StandardMethodCodec();
  final BinaryMessenger origin;

  DoKitBinaryMessenger(this.origin);

  @override
  Future<void> handlePlatformMessage(String channel, ByteData data, callback) {
    ChannelInfo info = saveMessage(channel, data, false);
    PlatformMessageResponseCallback wrapper = (ByteData data) {
      resolveResult(info, data);
      callback(data);
    };
    return origin.handlePlatformMessage(channel, data, wrapper);
  }

  @override
  Future<ByteData> send(String channel, ByteData message) async {
    ChannelInfo info = saveMessage(channel, message, true);
    ByteData result = await origin.send(channel, message);
    resolveResult(info, result);
    return result;
  }

  @override
  void setMessageHandler(
      String channel, Future<ByteData> Function(ByteData message) handler) {
    origin.setMessageHandler(channel, handler);
  }

  @override
  void setMockMessageHandler(
      String channel, Future<ByteData> Function(ByteData message) handler) {
    origin.setMockMessageHandler(channel, handler);
  }
}

用来hook的wrapper类需要调用oring对象的同名方法。但在1.20版本BinaryMessager增加了两个新方法checkMessageHandler和checkMockMessageHandler,如果使用1.17.5版本的flutter sdk去编译,就无法调用origin.checkMessageHandler方法,因为不存在;如果使用1.20.4版本的flutter sdk去编译,编译和发布没问题,但编出来的sdk在1.17.5的工程被引用后,也会因为checkMessageHandler方法不存在导致编译失败。 针对这种多个Flutter版本API不同导致的兼容性问题,可以使用扩展方法extension关键字来解决。 建立一个_BinaryMessengerExt类如下:

extension _BinaryMessengerExt on BinaryMessenger {
  bool checkMessageHandler(String channel, MessageHandler handler) {
    return this.checkMessageHandler(channel, handler);
  }

  bool checkMockMessageHandler(String channel, MessageHandler handler) {
    return this.checkMockMessageHandler(channel, handler);
  }
}

在1.17.5版本,调用origin.checkMessageHandler会走到扩展方法的checkMessageHandler中,编译能通过,由于这个方法在1.17.5中是绝对不会被调用到的,虽然会形成递归调用,但没影响。而在1.20版本,BinaryMessenger本身实现了checkMessageHandler方法,所以调用checkMessageHandler方法会走到BinaryMessenger的checkMessageHandler方法中,也能正常使用。 通过extentsion,只要以最低兼容版本的类作为基础,在扩展类中定义新版本中新增的API,就能解决多版本API兼容的问题。

总结

以上就是DoKit For Flutter的现有功能以及工具的基本原理介绍。 我们知道当前它的功能还不是完善,后续会继续不断深入的挖掘业务中的痛点并持续输出各种提高用户效率的工具,努力让DoKit For Flutter变得更加优秀期望。,符合大家的

DoKit一直追求给开发者提供最便捷和最直观的开发体验,同时我们也十分欢迎社区中能有更多的人参与到DoKit的建设中来并给我们提出宝贵的意见或PR。 DoKit的未来需要大家共同的努力。

文章来自来自掘金 DoKit。

开源组件DoraemonKit之Android版本技术实现(一) 一、引言 ​ DoraemonKit是滴滴开源的研发助手组件,目前支持iOS和Android两个平台。通过接入DoraemonKit组件,可以方便支持如下所示的多种调试工具: ​ 本文是DoraemonKit之Android版本技术实现系列文章的第一篇,主要介绍各个视觉工具的技术实现细节。 二、技术实现 2.1 取色器 方案对比 ​ 取色器工具可以通过颜色吸管获取屏幕任意位置的像素值,所以实现... 阅读详情

相关推荐

从论文到生产:iSLIP优先级匹配算法在SDN交换机中的20年演进史

本文回顾了iSLIP优先级匹配算法在SDN交换机中的20年演进历程,从斯坦福大学的原始论文到现代芯片实现。通过独特的指针滑动和迭代循环机制,iSLIP算法显著提升了交换机的吞吐量和公平性,解决了传统FIFO调度的队头阻塞问题。文章详细探讨了算法在硬件实现中的工程挑战、开源实践及未来AI时代的智能调度方向。

weixin_29230649的博客 331

Dokit 开源库:简化 Android 应用开发的利器

Dokit 是一款功能强大且易于集成的 Android 开发工具库,旨在帮助开发人员更轻松地进行应用调试、性能优化和用户体验改进。它提供了丰富的调试工具、性能监测和悬浮窗功能,使开发者可以更方便地查看应用的运行状态、性能指标和运行时信息。

特立独行的博客 4134

【第4章 光模块实测方法总结(环境搭建、眼图测试、接收测试、注意事项)】

本文系统介绍了光模块测试的完整流程与关键要点,涵盖低速模块到3.2T PAM4超高速模块的测试方法。内容包括:1)测试环境搭建(光路/电路要求);2)核心测试项目(眼图分析、接收灵敏度/饱和测试、误码压力测试);3)PAM4专项测试(TDECQ、RLM线性度等);4)可靠性测试(温循、电压、老化);5)八大注意事项(如禁止脏端面测试、长短距混插等)。特别强调高速模块对测试环境的高敏感性,需重点关注波形质量而非单纯光功率,并需进行严格压力测试才能暴露潜在问题。

学无止境 459

DoKit:一机多控WebView无侵入注入JS|滴滴开源

将滴滴技术设为“星标⭐️”第一时间收到文章更新导读自2018年正式对外开源以来,DoKit经历了五年的打磨,已经发展成一个相对完整的生态,支持六大平台(Android、iOS、Web、小程序、Flutter和PC),是滴滴开源委员会的精品孵化项目。在外部被众多头部企业广泛使用并获得了良好的口碑。在滴滴内部,DoKit已经在所有业务线和App中落地使用,基本覆盖所有日常开发和测试场景,提升了研发和质...

DiDi_Tech的博客 2877

Visual Studio 2022 社区版安装指南:从下载到配置的完整流程

本文详细介绍了Visual Studio 2022社区版的完整安装与配置流程,包括系统要求检查、官方下载步骤、工作负载选择、安装位置配置等关键环节。作为微软推出的免费集成开发环境,VS2022社区版支持多种编程语言,适合个人开发者和小型团队使用。文章还提供了常见问题解决和性能优化技巧,帮助用户高效完成开发环境搭建。

weixin_28829339的博客 889

Superpowers:可编程AI协作协议与Skill工程化实践

AI编程正从提示词驱动迈向工程化协作新范式。Superpowers并非传统代码补全工具,而是一套定义清晰、可版本控制、可调试复用的AI协作协议——它将AI能力抽象为带输入校验、执行管道、输出契约和元数据声明的Skill(类DSL构件),再通过状态驱动的Workflow编排实现跨平台、可熔断、含人工Checkpoint的自动化流水线。其核心价值在于解决AI生成代码长期存在的不可复现、不可审计、不可交接三大痛点,支撑OpenAPI转TS、Figma转Vue等高复用场景落地。本文深入解析Skill设计四重契约与P

weixin_31124163的博客 377

滴滴APM工具Dokit

Dokit是滴滴推出的一款APP性能分析工具。APP引入以后的界面。

joedan0104的专栏 2510

c语言串口编程详解

串口: 一种异步通信接口,通常用于低速数据传输。RS-232: 最常见的串口标准,定义了电气特性、连接器和信号线。UART: 通用异步收发传输器,是实现串口通信的硬件模块。通过以上内容,你应能够理解并实现C语言在Windows和Linux平台上的串口编程。希望这本手册能帮助你在实际项目中顺利进行串口通信开发。如果有任何疑问或需要进一步的帮助,请随时提问。

jkzyx123的博客 2224

滴滴DoKit For Flutter正式开源

原文链接:https://juejin.cn/post/6914111076099915784?utm_source=gold_browser_extension

Vito_Jianxue的博客 763

算法导论之线性规划

线性规划,充斥着运筹学,在图的单源最短路径求解差分约束系统就是用到线性规划。怎么样问题可以建模为线性规划来解决呢?在给定的有限的资源和竞争约束情况下,取得最大化或最小化目标的问题。导论中给出政治竞选问题、航空航线调度问题、钻井采油问题。最大化或最小化目标是函数的因变量,自变量就是资源的约束因素,其函数就是由这些制约因素构成的等式或不等式。下面数学定义下线性规划。 在一般线性规划问题中,最优化一个

医疗影像检索 2万+

后台管理系统-7-vue3之引入配置文件baseURL

mock=false,本地模拟。mock=true,线上模拟。baseURL+url=实际请求的URL。get请求param参数,post请求data参数。

qq_20466211的博客 208

【亲测免费】 探索高效开发的新纪元:DoKit——你的全能开发助手

探索高效开发的新纪元:DoKit——你的全能开发助手 【免费下载链接】DoKit didi/DoKit: 是一个跨平台的移动应用开发框架,提供了丰富的组件和工具,支持 iOS 和 Android。适合对移动应用开发、跨平台开发以及想要使用一套框架支持多个平台的开发者。 ...

gitblog_00075的博客 969

uniapp - 实现安卓App打包上架应用商店详细教程,详解Hbuilder打包编译apk发布上传到应用市场全流程,提供uniApp云打包、离线打包app、原生本地打包,附带APP备案和安卓证书申请

uni-app,安卓,APP,应用商店,打包编译apk,上架到应用市场,如何打包app并发布到主流应用市场,发布为AndroidApp流程,应用备案,如何申请安卓证书,hbuilder发布安卓apk后怎么上传到各家软件商店,创建app证书,uniapp发行原生APP本地打包安卓APK,详细最全的步骤教程,项目打包成apk,云打包,安心打包,安卓app离线打包,一直审核不通过,被拒绝,不符合规范,上架发布失败,申请安卓证书和获取证书信息,uni-app打包发布安卓Android软件到各大应用商店,腾讯应用

🏆 前端领域优质创作者 1万+

滴滴出行 DoKit 2.0 - 泛前端开发者的百宝箱

给我一个支点,我将撬动整个地球。 --阿基米德有了DoKit,我将帮你节省出一个年假。 ...

singwhatiwanna 5325

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

DoKit 开源项目教程

DoKit 开源项目教程 【免费下载链接】DoKit didi/DoKit: 是一个跨平台的移动应用开发框架,提供了丰富的组件和工具,支持 iOS 和 Android。适合对移动应用开发、跨平台开发以及想要使用一套框架支持多个平台的开发者。 ...

gitblog_00449的博客 678

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

如何用DoKit提升90%移动开发效率?一站式跨平台调试神器全攻略

DoKit是由滴滴出行开发的跨平台移动应用开发框架,集成了丰富的组件和工具,全面支持iOS、Android、小程序、Flutter和Web平台。无论是开发调试、性能优化还是视觉调整,DoKit都能提供一站式解决方案,让开发者告别繁琐的多平台适配工作,显著提升研发全生命周期效率。 ## ???? 为什么选择DoKit?三大核心优势解析 ### 1️⃣ 全平台覆盖,一套工具走天下 DoKit突破性实现...

gitblog_00239的博客 482

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Dokit: 你的可视化前端开发利器

Dokit: 你的可视化前端开发利器 是一个强大的前端开发辅助工具,它集成了多种实用功能,旨在提高开发者的工作效率,提供更便捷的前端调试环境。通过Dokit,开发者可以更好地理解和操作DOM,进行性能分析,并轻松实现组件交互和定制化扩展。 技术概览 Dokit 基于JavaScript和HTML5构建,采用WebExtension标准,因此它可以作为浏览器扩展在Chrome、Firefox等主流浏...

gitblog_00033的博客 559

滴滴开源的APM方案Dokit接入

自定义组件需要实现 IKit 接口,该接口对应哆啦A梦功能面板中的组件。以代驾乘客端为例,实现环境切换组件如下。) {} }在初始化的时候注册自定义组件。DoKit . Builder(this) . productId("需要使用平台功能的话,需要到dokit.cn平台申请id") . customKits(mapKits) . build() }DoKit入口api/*** 主icon是否处于显示状态* 显示主icon} /*** 直接显示工具面板页面} /*** 直接隐藏工具面板。

xiangzhihong8的专栏 3056

【免费下载】 DoKit iOS开发调试工具集成与使用指南

DoKit(原名DoraemonKit)是一款功能强大的iOS开发调试工具集,由滴滴开源团队开发维护。它为开发者提供了一系列便捷的调试功能,包括但不限于: - 性能监控(CPU、内存、FPS等) - 视图层级检查 - 网络请求监控 - 日志查看 - 模拟定位 - 数据库调试 - 内存泄漏检测 这些功能可以帮助开发者在开发阶段快速定位和解决问题,提高开发效率。 ## 二、集成方式详解 ###...

gitblog_00868的博客 894

滴滴正式发布开源客户端研发助手 DoKit 3

为了让Dokit的端上能力得延伸和扩展,同时也是为了更好的服务好我们的每一个业务方,让DoKit成为一个能够满足泛前端开发、测试、设计等等各方都需要的功能丰富的通用型平台。我们组内经过讨论决定推出dokit.cn。平台端主要包含以下几项内容:1)用户登录2)使用中心3)产品中心: 包含接口Mock和健康体检的功能详细介绍4)控制台: 主要提供产品管理、用户管理、数据Mock、健康体检等功能。必须登录以后才能访问,你可以创建的每一个产品。然后需要将你的ProductId集成到Android和iOS中去。

onghaha的博客 827

终极指南:5分钟掌握DoKit跨平台开发神器

想要快速提升移动应用开发效率吗?DoKit跨平台开发工具正是你需要的终极解决方案!作为一款功能强大的**跨平台移动应用开发工具**,DoKit为iOS、Android、Flutter和小程序开发者提供了完整的调试和优化套件,让你的开发工作变得前所未有的简单高效。 ## 🚀 DoKit是什么?为什么你需要它? DoKit是由滴滴出行开源的**一站式移动应用开发工具集**,专为移动应用开发者设计

gitblog_00797的博客 501

滴滴正式发布开源客户端研发助手DoKit 3.0,新特性解读

DoKit3.0 - 不只是工具

u013712343的博客 535
上一篇: 面试官一套RxJava组合拳下来,我被问得怀疑人生
下一篇: 阿里巴巴的中台架构PPT告诉你,数据中后和业务中台有什么关系?
懂你的大海
博客等级 码龄6年 9049粉丝 1381原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值