iOS端flutter_map手势缩放触发ClientException异常求助
iOS上flutter_map缩放地图触发"Too many open files"错误的解决办法
问题原因
iOS系统默认文件描述符(socket连接属于此类)上限较低,手指缩放地图时,flutter_map会同时发起大量OpenStreetMap瓦片请求,每个请求对应一个socket连接,短时间内打开的连接数超过系统限制,就会抛出errno=24的错误。Android系统文件描述符限制更高,因此不会出现该问题。
解决方案
1. 限制请求并发数+启用瓦片缓存
修改TileLayer配置,限制同时发起的瓦片请求数量,并启用缓存减少重复请求:
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin { final MapController _mapController = MapController(); LatLng currentPosition = const LatLng(52.5200, 13.4050); // 创建内存缓存,最多缓存100个瓦片 final tileCache = MemoryCache(maxSize: 100); @override Widget build(BuildContext context) { return Scaffold( extendBodyBehindAppBar: true, floatingActionButton: Column( mainAxisAlignment: MainAxisAlignment.end, children: <Widget>[ SizedBox( height: 50.0, width: 50.0, child: FittedBox( child: FloatingActionButton( heroTag: "getCurrentLocation_bnb", backgroundColor: Colors.white, child: const Icon(Icons.my_location, color: Colors.black), onPressed: () { // 无需setState,mapController.move会自动触发地图更新 _mapController.move(currentPosition, 17); }, ), ), ), ], ), body: FlutterMap( mapController: _mapController, options: const MapOptions( initialCenter: LatLng(52.5200, 13.4050), initialZoom: 5, maxZoom: 18, minZoom: 5, ), children: <Widget>[ TileLayer( urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', // 限制并发请求数,iOS建议设为5-10 maxConcurrentRequests: 6, // 启用内存缓存 tileCache: tileCache, // 缩放时节流瓦片更新,避免频繁请求 tileUpdateTransformer: TileUpdateTransformer.throttle( const Duration(milliseconds: 200), ), ), ], ), ); } }
2. 优化iOS系统配置(可选)
如果上述方法效果有限,可调整iOS应用的文件描述符限制:
- 打开iOS项目的
Runner/Info.plist - 添加以下键值对:
<key>NSFileProtectionNone</key> <false/> <key>UIFileSharingEnabled</key> <true/>
3. 使用磁盘缓存瓦片插件(进阶)
用flutter_map_cached_tile_layer替代默认TileLayer,将瓦片缓存到本地磁盘,大幅减少重复网络请求:
- 在
pubspec.yaml添加依赖:
dependencies: flutter_map_cached_tile_layer: ^最新版本号
- 替换
TileLayer为CachedTileLayer:
CachedTileLayer( urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', maxConcurrentRequests: 6, cacheOptions: const CacheOptions( storeDirectory: 'osm_tiles', maxStoreSize: 1024 * 1024 * 50, // 最多缓存50MB瓦片 ), )
内容的提问来源于stack exchange,提问作者user13931873
相关产品推荐
相关产品推荐

