【问题标题】:Flutter Plugin access native objectsFlutter Plugin 访问原生对象
【发布时间】:2022-11-17 03:16:54
【问题描述】:

我正在开发一个 Flutter 插件来在 Flutter 中实现一个 iOS SDK 和一个 Android SDK。在这两个原生SDK中,都有一个叫做Peripheral的对象,它是一个扩展和实现其他对象的复杂对象。如果我想使用这些对象,我是否也必须在 Flutter 中实现它们?或者我可以从 dart 中创建这些对象的操作实例吗?

现在,我正在尝试通过一个 PeripheralObject 来操作实例,该对象在构造函数中调用一个函数,该函数将在外围设备的本机 Java(适用于 Android)中创建一个实例,将其放置在哈希映射中,并将其内存地址返回给飞镖.在 dart 中,我保留 Java 对象的内存地址,当我调用一个函数时,比如 getName,我将 java 内存地址传递给方法通道,这样,我可以从映射中检索我的本机对象实例,调用该方法并发回答案。这是解决问题的好方法还是有其他更好的方法?

这是我的飞镖对象:

class Peripheral {
  late String _objectReference;
  late String _localName, _uuid;

  Peripheral({required String localName, required String uuid}) {
    _uuid = uuid;
    _localName = localName;
    _newPeripheralInstance(localName, uuid);
  }


  Future<void> _newPeripheralInstance(String localName, String uuid) async {
    _objectReference = (await PeripheralPlatform.instance.newPeripheralInstance(localName, uuid))!;
    return;
  }

  String get objectReference => _objectReference;

  Future<String?> getModelName() async {
    return PeripheralPlatform.instance.getModelName(_objectReference);
  }

  Future<String?> getUuid() async {
    return PeripheralPlatform.instance.getUuid(_objectReference);
  }
}

这是我的 Dart 方法频道:

class MethodChannelPeripheral extends PeripheralPlatform {
  /// The method channel used to interact with the native platform.
  @visibleForTesting
  final methodChannel = const MethodChannel('channel');

  @override
  Future<String?> newPeripheralInstance(String localName, String uuid) async {
    String? instance = await methodChannel.invokeMethod<String>('Peripheral-newPeripheralInstance',  <String, String>{
      'localName': localName,
      'uuid': uuid
    });
    return instance;
  }

  @override
  Future<String?> getModelName(String peripheralReference) {
    return methodChannel.invokeMethod<String>('Peripheral-getModelName', <String, String>{
      'peripheralReference': peripheralReference
    });
  }

  @override
  Future<String?> getUuid(String peripheralReference) {
    return methodChannel.invokeMethod<String>('Peripheral-getUuid', <String, String>{
      'peripheralReference': peripheralReference
    });
  }
}

这是我的 Android Java 文件:

public class PluginPeripheral {
  private static Map<String, Peripheral> peripheralMap = new HashMap<>();

  public static void handleMethodCall(String method, MethodCall call, MethodChannel.Result result) {
    method = method.replace("Peripheral-", "");
    switch (method) {
      case "newPeripheralInstance":
        newPeripheralInstance(call, result);
        break;
      case "getModelName":
        getModelName(call, result);
        break;
      case "getUuid":
        getUuid(call, result);
        break;
      default:
        result.notImplemented();
        break;
    }
  }

  private static void newPeripheralInstance(MethodCall call, MethodChannel.Result result) {
    if (call.hasArgument("uuid") && call.hasArgument("localName")) {
      String uuid = call.argument("uuid");
      String localName = call.argument("localName");
      if (localName == null || uuid == null) {
        result.error("Missing argument", "Missing argument 'uuid' or 'localName'", null);
        return;
      }
      Peripheral peripheral = new Peripheral(localName, uuid);
      peripheralMap.put(peripheral.toString(), peripheral);
      result.success(peripheral.toString());
    }
  }

  private static void getModelName(MethodCall call, MethodChannel.Result result) {
    if (call.hasArgument("peripheralReference")) {
      String peripheralString = call.argument("peripheralReference");
      if (peripheralString == null) {
        result.error("Missing argument", "Missing argument 'peripheral'", null);
        return;
      }
      Peripheral peripheral = peripheralMap.get(peripheralString);
      if (peripheral == null) {
        result.error("Invalid peripheral", "Invalid peripheral", null);
        return;
      }
      result.success(peripheral.getModelName());
    } else {
      result.error("Missing argument", "Missing argument 'peripheralReference'", null);
    }
  }

  private static void getUuid(MethodCall call, MethodChannel.Result result) {
    if (call.hasArgument("peripheralReference")) {
      String peripheralString = call.argument("peripheralReference");
      if (peripheralString == null) {
        result.error("Missing argument", "Missing argument 'peripheral'", null);
        return;
      }
      Peripheral peripheral = peripheralMap.get(peripheralString);
      if (peripheral == null) {
        result.error("Invalid peripheral", "Invalid peripheral", null);
        return;
      }
      result.success(peripheral.getUuid());
    } else {
      result.error("Missing argument", "Missing argument 'peripheralReference'", null);
    }
  }
}

【问题讨论】:

    标签: java flutter dart plugins native


    【解决方案1】:

    另一种方法是在 Android 中将对象转换为地图,然后再在 Flutter 中转换回对象。是这样的:

    颤振/飞镖:

    class Device {
      String? id;
      String? name;
    
    ...
      Device.fromMap(Map<String, dynamic> map) {
        id = map['id'];
        name = map['name'];
      }
    }
    
    final map = await methodChannel.invokeMethod('requestDevice');
    final device = Device.fromMap(map.cast<String, dynamic>());
    

    安卓/科特林:

    data class Device(
        val id: String,
        val name: String?
    ) {
    
    ...
        fun toMap(): Map<String, Any?> {
            return mapOf(
                "id" to id,
                "name" to name
            )
        }
    }
    
    override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
    ...
        result.success(device.toMap())
    ...
    }
    

    【讨论】:

      猜你喜欢
      • 2021-03-14
      • 1970-01-01
      • 1970-01-01
      • 2023-01-27
      • 1970-01-01
      • 2020-10-08
      • 2014-11-26
      • 1970-01-01
      • 2023-01-26
      相关资源
      最近更新 更多