You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中background_locator_2插件Android端跨Isolate传LocationDto报错

问题与解决方案:background_locator_2 Android端隔离间通信错误

问题概述

使用background_locator_2(版本2.0.6-dev.2)实现后台位置获取功能,iOS端运行正常,但在Flutter和Kotlin版本更新后,Android端出现隔离间通信错误,错误信息如下:

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Invalid argument: is a regular instance: Instance of 'LocationDto'
E/flutter (26006): #0      _SendPort._sendInternal (dart:isolate-patch/isolate_patch.dart:249:43)
E/flutter (26006): #1      _SendPort.send (dart:isolate-patch/isolate_patch.dart:230:5)
E/flutter (26006): #2      LocationServiceRepository.callback
package:drivers_app/tabPages/location_service_reposirtory.dart:59

错误指向LocationServiceRepository类中send?.send(locationDto);一行,原因是Dart隔离间仅支持传递可序列化对象(基本类型、List、Map或实现序列化协议的类),而LocationDto是普通实例,无法直接跨隔离间传递。

解决方案

方案1:将LocationDto转换为Map传递

修改LocationServiceRepository的callback方法,把LocationDto转为Map后发送,接收端再重建对象:

@pragma('vm:entry-point')
Future<void> callback(LocationDto locationDto) async {
  print('$_count location in dart: ${locationDto.toString()}');
  await setLogPosition(_count, locationDto);
  final SendPort? send = IsolateNameServer.lookupPortByName(isolateName);
  
  // 转换LocationDto为Map
  final locationMap = {
    'latitude': locationDto.latitude,
    'longitude': locationDto.longitude,
    'accuracy': locationDto.accuracy,
    'altitude': locationDto.altitude,
    'speed': locationDto.speed,
    'speedAccuracy': locationDto.speedAccuracy,
    'heading': locationDto.heading,
    'time': locationDto.time,
    'isMocked': locationDto.isMocked,
  };
  send?.send(locationMap); // 发送Map替代原对象
  _count++;
}

接收端updateUI方法重建LocationDto:

Future<void> updateUI(dynamic data) async {
  if (data is Map) {
    final locationDto = LocationDto(
      latitude: data['latitude'],
      longitude: data['longitude'],
      accuracy: data['accuracy'],
      altitude: data['altitude'],
      speed: data['speed'],
      speedAccuracy: data['speedAccuracy'],
      heading: data['heading'],
      time: data['time'],
      isMocked: data['isMocked'],
    );
    await _updateNotificationText(locationDto);
  }
}

方案2:让LocationDto实现序列化

通过json_serializable包让LocationDto支持序列化,适用于需要完整传递对象的场景:

  1. 依赖配置(pubspec.yaml):
dependencies:
  json_annotation: ^4.8.1

dev_dependencies:
  build_runner: ^2.4.4
  json_serializable: ^6.7.0
  1. 修改LocationDto类(若为插件类,可复制到本地修改):
import 'package:json_annotation/json_annotation.dart';

part 'location_dto.g.dart';

@JsonSerializable()
class LocationDto {
  final double latitude;
  final double longitude;
  final double accuracy;
  final double altitude;
  final double speed;
  final double speedAccuracy;
  final double heading;
  final int time;
  final bool isMocked;

  LocationDto({
    required this.latitude,
    required this.longitude,
    required this.accuracy,
    required this.altitude,
    required this.speed,
    required this.speedAccuracy,
    required this.heading,
    required this.time,
    required this.isMocked,
  });

  factory LocationDto.fromJson(Map<String, dynamic> json) => _$LocationDtoFromJson(json);
  Map<String, dynamic> toJson() => _$LocationDtoToJson(this);
}
  1. 生成序列化代码:
flutter pub run build_runner build
  1. 修改发送和接收逻辑:
// 发送端
send?.send(locationDto.toJson());

// 接收端
Future<void> updateUI(dynamic data) async {
  if (data is Map) {
    final locationDto = LocationDto.fromJson(data.cast<String, dynamic>());
    await _updateNotificationText(locationDto);
  }
}

方案3:仅传递所需字段

若仅需部分字段(如经纬度),可直接传递单个字段或精简Map:

// 发送端
send?.send({
  'lat': locationDto.latitude,
  'lng': locationDto.longitude,
});

// 接收端
Future<void> updateUI(dynamic data) async {
  if (data is Map) {
    await BackgroundLocator.updateNotificationText(
      title: "Your location is updated",
      msg: "${DateTime.now()}",
      bigMsg: "${data['lat']}, ${data['lng']}",
    );
  }
}

内容的提问来源于stack exchange,提问作者Pannam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 22:45:41