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等等

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

相关推荐
致Great1 天前
Nano Banana提示语精选
人工智能·gpt·chatgpt·开源·agent
chxii1 天前
开源项目 lottery_results
开源
十六年开源服务商1 天前
WordPress站内SEO优化最佳实践指南
大数据·开源
weixin_377634841 天前
【开源RAG】InstructRAG 过滤无关召回内容 提高问答准确率
开源·rag
小老鼠不吃猫1 天前
深入浅出(六)序列化库 FlatBuffers、Protobuf、MessagePack
c++·开源·buffer
xlp666hub1 天前
C语言实战:手搓高并发异步日志库(基于 Ring Buffer + 生产者消费者模型)
开源
周杰伦_Jay1 天前
【LangGraph】图结构智能体框架核心特性
python·开源
中冕—霍格沃兹软件开发测试1 天前
测试工具链的构建与团队协作:从工具集成到价值流动
人工智能·科技·测试工具·开源·appium·bug
HyperAI超神经1 天前
活动回顾丨 北大/清华/Zilliz/MoonBit共话开源,覆盖视频生成/视觉理解/向量数据库/AI原生编程语言
人工智能·ai·开源·编程语言·向量数据库·视频生成·视觉理解