Flutter Aop 面向切面编程 aspect_frontend_server 前世今生

面向切面编程在java中是很常见的运用,它可以很容易的在不改动已有代码的情况下加入自己的代码逻辑。 一些jdk核心代码,我们没有办法直接编辑,也可以通过这种方式进行修改。在Java中做到这些很容易,因为Java有一整套反射机制。

在Flutter中,做到这些就有些困难,为了更好的性能,Flutter中的Dart阉割了它的反射功能。

在过往的时间里也出现了一些可以用来做Flutter Aop的工具:

1.XianyuTech/aspectd

最早是闲鱼团队发起的,但是已经很久没有更新,SDK支持版本仍然停留在2.5。

2.Beike_AspectD

贝壳团队在Aspectd基础上进行了改造和适配,但最新SDK也只支持到3.10.5

3.sa_flutter_aspectd

神策团队基于aspectd做的一些改造,专门为它们信息采集做服务,但更新记录只停留在2022年。

4.aspect_frontend_server

它是我在得知aspectd不支持2.5后续版本后,借鉴了aspectd代码,并重写的一套Flutter Aop面向切面编程框架,从2021年开始更新一直至今,已经支持最新的flutter 3.38.1。

aspect_frontend_server虽然是借鉴了aspectd代码的代码,但可以说是完全重写,它去掉了很多原本aspectd中的功能,只保留了最基本的aop功能,也就是拦截某个方法的运行,可以在它运行的前后插入自己的运行逻辑。设置上完全替换到原有逻辑。

aspect_frontend_server的集成方法也很简单。只需要替换到原本flutter中的frontend_server_aot.dart.snapshot文件,不需要引入任何额外的库。

通过aspect_frontend_server写入一个注入例子也很简单,下面是一个简单的例子:

在mian.dart文件中我们写入:

dart 复制代码
import 'inject.dart';

在injiect.dart中写入:

dart 复制代码
@pragma('vm:entry-point')
@pragma("aopd:inject", {
    //注入的包名
    "importUri": "package:flutter/src/gestures/binding.dart",
    //注入的类名
    "clsName": "GestureBinding",
    //注入的方法名
    "methodName": "-dispatchEvent",
    //是否符号匹配
    "isRegex": false
})
//必须是static,不然不起作用
static dynamic dispatchEvent(
    Object target,
    String functionName,
    List<dynamic> positionalParams,
    Map<dynamic, dynamic> namedParams,
    Function proceed) {
        PointerEvent event = positionalParams[0];
        HitTestResult? hitTestResult = positionalParams[1];
        debugPrint('dispatchEvent - start ${event.kind.name}');
        return proceed.call(event, hitTestResult);
}

上面的例子可以拦截所有Flutter底层传递给应用层的触摸事件,如果我们需要分析用户的行为,通过在这个函数上插桩就可以很容易实现。

aspect_frontend_server的用法还有很多,例如静态方法插桩,mixin插桩,extension插桩等等。可以自己下载项目运行example了解。

aspect_frontend_server相对于aspectd有很大不同:

  1. aspectd不支持flutter 2.5.4以上,本项目最高支持到2.38.1
  2. aspectd使用前需要对flutter tools的代码进行修改,本项目只需要替换flutter sdk对应的frontend_server.dart.snapshot即可
  3. aspectd的实现原理过于复杂,本项目去掉了Call,Inject等用法保留了Execute用法的同时对注入逻辑进行了简化
  4. aspectd还需要aspect_impl等,本项目可以直接在主程序代码中添加注入代码,也可以用plugin的方式添加
  5. 本项目不需要引入任何第三方包,用pragma注解完成对应插桩
  6. 支持hot restart,aspectd的注入代码修改后,需要重启程序才能看到改变,这样很不利于差桩代码的编写,aspect_frontend_server的差桩代码在改变后可以直接通过hot restart就能看到最新的改变。

在维护aspect_frontend_server过程中也碰到了一些bug,感谢反馈bug的小伙伴。目前已知的问题已经修复:

  1. extionsion和mixin方法注入
  2. 实现try-catch的注入
  3. 实现getter方法的注入
  4. 解决函数返回值为Futnre 范型报错的问题
  5. 解决编译添加--obfuscate混淆出错的问题
  6. 解决isRegex参数某些情况不起作用的bug等等

希望有更多的小伙伴使用并反馈问题,我会一直将这个项目维护下去。

相关推荐
晚霞的不甘19 分钟前
Flutter for OpenHarmony 实现计算几何:Graham Scan 凸包算法的可视化演示
人工智能·算法·flutter·架构·开源·音视频
猫头虎32 分钟前
OpenClaw-VSCode:在 VS Code 里玩转 OpenClaw,远程管理+SSH 双剑合璧
ide·vscode·开源·ssh·github·aigc·ai编程
一只大侠的侠37 分钟前
Flutter开源鸿蒙跨平台训练营 Day12从零开发通用型登录页面
flutter·开源·harmonyos
wenzhangli740 分钟前
OoderAgent 企业版 2.0 发布的意义:一次生态战略的全面升级
人工智能·开源
rainbow688943 分钟前
C++开源库dxflib解析DXF文件实战
开发语言·c++·开源
猫头虎44 分钟前
基于信创openEuler系统安装部署OpenTeleDB开源数据库的实战教程
数据库·redis·sql·mysql·开源·nosql·database
零一iTEM1 小时前
MAX98357A_音频输出测试
单片机·嵌入式硬件·开源·音视频·硬件工程
猫头虎2 小时前
如何使用Docker部署OpenClaw汉化中文版?
运维·人工智能·docker·容器·langchain·开源·aigc
一只大侠的侠2 小时前
Flutter开源鸿蒙跨平台训练营 Day 15React Native Formik 表单实战
flutter·开源·harmonyos
yumgpkpm2 小时前
预测:2026年大数据软件+AI大模型的发展趋势
大数据·人工智能·算法·zookeeper·kafka·开源·cloudera