欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

请添加图片描述

前言

Dart 语言本身是支持反射的(dart:mirrors),但在 Flutter 中,为了减小包体积、支持 Tree Shaking(摇树优化)和 AOT 编译,官方彻底禁用了 dart:mirrors
这导致很多依赖反射的经典设计模式(如:依赖注入、ORM 映射、动态代理)在 Flutter 中无法直接实现。

reflectable 是这一问题的官方解决方案。它使用**代码生成(Code Generation)**技术,在编译时分析代码,生成静态的反射元数据。这样既实现了类似反射的功能(通过名称调用方法、获取注解),又完全兼容 Flutter 的 AOT 模式。

对于 OpenHarmony 开发者,如果你需要移植 Java/Android 中重度依赖反射的框架(如 Retrofit, Gson),reflectable 是你必须掌握的黑科技。

一、核心原理

reflectable 不在运行时去“探索”类结构,而是要求你在编译前定义“我需要反射哪些能力”。

build_runner

分析

编译进 App

运行时查表

源代码 + @Reflector

Reflectable代码生成器

生成 .reflectable.dart

最终鸿蒙 HAP

调用方法/读取注解

替代了 dart:mirrors 的运行时扫描

二、OpenHarmony 适配说明

reflectable 依赖 build_runner 进行代码生成。
生成的代码是标准的 Dart 代码,完全兼容 OpenHarmony

注意
鸿蒙应用的开发流程通常也有 build_runner 环节。确保在运行 flutter build hap 之前,先执行了 dart run build_runner build

三、基础用例

3.1 定义反射器 (Reflector)

首先,你需要定义一个类来描述你需要什么反射能力(比如:需要调用方法、需要读取注解)。

import 'package:reflectable/reflectable.dart';

// 定义一个反射能力配置
// 这里我们要求支持:调用实例方法、读取元数据
class MyReflectable extends Reflectable {
  const MyReflectable()
      : super(invokingCapability, metadataCapability);
}

const myReflector = MyReflectable();

在这里插入图片描述

3.2 标记类与使用反射

import 'package:reflectable/reflectable.dart';
import 'main.reflectable.dart'; // 生成的文件

// 1. 标记这个类需要被反射

class User {
  String name;
  User(this.name);

  void sayHello(String msg) {
    print('$name says: $msg');
  }
}

void main() {
  // 必须先初始化生成的反射数据
  initializeReflectable();

  var user = User('HarmonyOS');
  
  // 2. 获取反射镜像
  var instanceMirror = myReflector.reflect(user);

  // 3. 动态调用方法
  instanceMirror.invoke('sayHello', ['Hello World']);
  // 输出: HarmonyOS says: Hello World
}

在这里插入图片描述

四、完整实战示例:打造一个简易的 JSON 序列化器

虽然 json_serializable 很流行,但它需要为每个类写 g.dart。这里我们用 reflectable 实现一个通用的序列化函数,这更接近 Gson/Jackson 的体验。

import 'package:reflectable/reflectable.dart';
// 假设这是生成的代码文件,实际运行前需 build_runner
// import 'json_demo.reflectable.dart'; 

// 1. 定义序列化反射器
class JsonReflector extends Reflectable {
  const JsonReflector()
      : super(
          invokingCapability, // 调用 Getter
          declarationsCapability, // 获取字段列表
          typeRelationsCapability, // 获取父类信息
        );
}

const jsonReflect = JsonReflector();

// 2. 标记数据类

class Product {
  String name;
  double price;
  bool inStock;

  Product(this.name, this.price, this.inStock);
}


class Order {
  String orderId;
  Product product;
  
  Order(this.orderId, this.product);
}

// 3. 通用序列化函数
Map<String, dynamic> toJson(Object obj) {
  // 如果是基本类型直接返回
  if (obj is String || obj is num || obj is bool) return obj as dynamic;
  
  // 获取对象的反射镜像
  // 注意:实际项目中要处理异常,比如 obj 没有被标记 @jsonReflect
  var instanceMirror = jsonReflect.reflect(obj);
  var classMirror = instanceMirror.type;
  
  var map = <String, dynamic>{};

  // 遍历所有声明 (字段/Getter)
  for (var decl in classMirror.declarations.values) {
    if (decl is VariableMirror) { // 是变量
      var fieldName = decl.simpleName;
      var value = instanceMirror.invokeGetter(fieldName);
      
      // 递归序列化
      map[fieldName] = toJson(value!); 
    }
  }
  return map;
}

// 模拟 main
void main() {
  // initializeReflectable(); // 务必调用
  
  var order = Order(
    'ORD-2026', 
    Product('Mate 70', 6999.0, true)
  );

  var jsonMap = toJson(order);
  print(jsonMap);
  // 预期输出:
  // {
  //   orderId: ORD-2026, 
  //   product: {
  //     name: Mate 70, 
  //     price: 6999.0, 
  //     inStock: true
  //   }
  // }
}

在这里插入图片描述

五、总结

reflectable 是 Flutter/Dart 后设编程(Metaprogramming)的基石。
它虽然配置稍显繁琐(需要 build_runner),但它赋予了开发者在 AOT 限制下实现高度动态化架构的能力。

在 OpenHarmony 项目中,如果你需要实现:

  1. 插件化架构:通过字符串名称加载对应的 UI 组件。
  2. 通用 ORM:将对象映射到 SQLite 数据库表。
    reflectable 将是你不可或缺的工具。
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐