flutter_foreground_task 3.10.0在SDK33发布版中SendPort/ReceivePort失效崩溃
flutter_foreground_task 3.10.0在SDK33发布版中SendPort/ReceivePort崩溃的修复方案
针对你遇到的SDK33发布构建中SendPort/ReceivePort回调失效、应用崩溃的问题,结合你的代码,给出以下修复方向:
1. 修复代码混淆问题
SDK33发布版默认开启R8混淆,可能破坏flutter_foreground_task的Isolate通信机制。在Android项目的android/app/proguard-rules.pro中添加以下规则,保护相关类不被混淆:
-keep class com.pravera.flutter_foreground_task.** { *; } -keep class io.flutter.plugin.common.MethodChannel { *; } -keep class io.flutter.plugin.common.BinaryMessenger { *; } -keep class io.flutter.view.FlutterNativeView { *; } -keep class io.flutter.embedding.engine.FlutterEngine { *; }
2. 规范ReceivePort生命周期管理
你代码中注释了closeReceivePort(),会导致多次注册ReceivePort时出现端口泄漏,引发崩溃。取消注释该行,确保每次注册新端口前关闭旧的:
registerReceivePort(await FlutterForegroundTask.receivePort); void registerReceivePort(ReceivePort? receivePort) { closeReceivePort(); // 取消注释这行,先关闭旧端口 if (receivePort != null) { _receivePortForeground = receivePort; _receivePortForeground?.listen((position) { // 剩余逻辑... }); } }
3. 完善空安全检查,避免空指针崩溃
你代码中大量使用!强制解包,发布版中如果对象为空会直接崩溃。添加空判断并优化UI操作时机:
_receivePortForeground?.listen((position) { if (position == null) return; currentLatLng = LatLng(position.latitude, position.longitude); previousLatLngFromServer = currentLatLng; Prefs().setLasKnowLatLng(position.latitude, position.longitude); Prefs().setDouble(Prefs.bearing, position.heading); if(isTripStarted && vehicleMarker != null && googleMapController != null){ AnimateMarker(onMarkerPosUpdate: (Marker marker) { locationMarkers.remove(vehicleMarker); vehicleMarker = marker; locationMarkers.add(vehicleMarker!); // 确保UI操作在主线程帧回调中执行 WidgetsBinding.instance.addPostFrameCallback((_) { googleMapController!.animateCamera(CameraUpdate.newCameraPosition( CameraPosition( target: LatLng(marker.position.latitude, marker.position.longitude), zoom: 16.5 ) )); notifyListeners(); }); }).animaterMarker(vehicleMarker!.position, currentLatLng, vehicleMarker!); findSegment(); } updateLocationToServer(); });
4. 适配SDK33的权限要求
SDK33新增POST_NOTIFICATIONS权限,前台服务定位需要FOREGROUND_SERVICE_LOCATION权限,确保在AndroidManifest.xml中声明:
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
并在启动前台服务前动态请求POST_NOTIFICATIONS权限:
if (Platform.isAndroid && await Permission.notification.isDenied) { await Permission.notification.request(); }
5. 确保数据序列化正确性
Isolate之间传递的position对象必须是可序列化的类型(如基本类型、List、Map,或符合Isolate传递规则的自定义类)。如果是自定义位置类,避免包含不可序列化的成员(如函数、资源句柄等)。
内容的提问来源于stack exchange,提问作者NAGARAJ K
相关产品推荐
相关产品推荐

