Flutter安卓端用shelf搭本地服务器报错:找不到assets目录如何解决?
解决Flutter中使用shelf_static访问assets目录报错的问题
问题根源
Flutter的assets资源是打包到应用程序bundle中的,并非设备文件系统上的真实目录。而shelf_static的createStaticHandler默认是从本地文件系统路径读取文件,直接传入'assets'会因为找不到对应文件系统目录而报错。
解决步骤
1. 添加依赖
在pubspec.yaml中添加path_provider包,用于获取设备的临时目录:
dependencies: flutter: sdk: flutter shelf: ^1.4.0 shelf_static: ^1.1.2 path_provider: ^2.1.1
2. 复制Assets到临时目录
先将assets中的文件复制到设备的临时目录(该目录属于文件系统路径,shelf_static可以访问),再启动服务器:
import 'dart:io'; import 'dart:typed_data'; import 'package:flutter/services.dart'; import 'package:path_provider/path_provider.dart'; import 'package:shelf/shelf.dart'; import 'package:shelf/shelf_io.dart' as io; import 'package:shelf_static/shelf_static.dart'; Future<void> _startShelfLocalhostServer() async { // 1. 获取设备临时目录 final tempDir = await getTemporaryDirectory(); final targetDir = Directory('${tempDir.path}/assets'); // 2. 创建目标目录(如果不存在) if (!await targetDir.exists()) { await targetDir.create(recursive: true); } // 3. 复制index.html到临时目录 final assetBytes = await rootBundle.load('assets/index.html'); final file = File('${targetDir.path}/index.html'); await file.writeAsBytes( assetBytes.buffer.asUint8List( assetBytes.offsetInBytes, assetBytes.lengthInBytes, ), ); // 4. 使用临时目录作为静态文件路径 var handler = createStaticHandler(targetDir.path, defaultDocument: 'index.html'); var cascade = Cascade().add(handler).add(_echoRequest); var server = await io.serve(cascade.handler, '0.0.0.0', 8080); print('Server listening on ${server.address.host}:${server.port}'); } Response _echoRequest(Request request) { return Response.ok('Request for "${request.url}"'); }
补充说明
- 如果assets目录下有多个文件/子目录,需要递归遍历并复制所有资源,可通过
rootBundle.loadStructuredData或遍历asset清单实现。 - 使用
0.0.0.0代替localhost,可以让同一局域网内的设备访问该服务器(如果需要的话)。 - 临时目录的文件会在应用重启或系统清理时被删除,若需要持久化可改用
getApplicationDocumentsDirectory。
内容的提问来源于stack exchange,提问作者iqfareez
相关产品推荐
相关产品推荐

