原问题
我写了一个 Dart 包,我的 flutter 应用程序正在使用它。
在 dart 包中,我想将一些静态数据存储在一个 json 文件中,我想从 dart 包代码中读取该文件。
但是我找不到直接从 dart 包访问 Assets 文件的方法。使用 File(path).readAsString()
仅适用于 dart 控制台应用程序并使用 rootBundle
仅适用于 flutter 包/应用程序。
我的问题是:如何直接从纯 dart 包访问存储在 dart 包 Assets 中的这个文件?
在 flutter 包中,我只需像这样通过 pubspec.yml 使文件可用
flutter:
assets:
- lib/assets/b737.json
但是我找不到纯 Dart 包的类似解决方案。任何帮助表示赞赏。
答案
经过长时间的研究和社区的良好帮助,此功能似乎根本不存在。
但是有解决方法:
从 Flutter 项目加载并将读取字符串传递给 dart 包
通过
rootBundle.loadString()
从 flutter 项目加载 Assets 文件并在 flutter 中指定 Assets 文件 pubspec.yaml
并将字符串数据传递给 dart 包。查询 ch271828n's answer for details使其成为 flutter 包
一个简单的解决方案是将纯 dart 包转换为 flutter 包。然后它不再是纯粹的 Dart ,但这并不总是伤害。特别是,当包在另一个 flutter 项目/包中使用时。
将原始数据保存在变量 中
除了在运行时提供 Assets 文件和读取内容之外,您还可以直接将 Assets 文件内容安全地保存到
static const
多变的。然而,对于更大的 Assets ,如果它从 Assets 中索引数千行,这可能会减慢你的 IDE。从分析器中排除这些文件可能会有所帮助:analysis_options.dart
analyzer:
exclude:
- '**/assets/data/**'
白杨木包装您也可以查看 aspen有助于解决先前解决方案的软件包。您指定 Assets 的路径,然后通过代码生成将这些文件的内容保存到可直接从代码中获得的变量中。
part 'assets.g.dart';
// @Asset is an annotation from package:aspen that marks the asset to be packed.
@Asset('asset:my_package/web/my-asset.txt')
// We create a const (it must be const!) value that holds the generated asset content.
const myTextAsset = TextAsset(text: _myTextAsset$content);
最佳答案
乍一看这是“不可能的”,因为 Dart 包可以在任何地方使用 - 例如在非 Flutter 环境中使用。然后真的没有办法找到。
但是,有一个解决方法:inverse of control .示例代码:
// pure dart package
abstract class AbstractAssetFileFetcherService {
String getAssetFileContent(String assetName);
}
AbstractAssetFileFetcherService? service;
void myFunctionThatUsesAssetFile() {
var myFirstFileContent = service.getAssetFileContent('my-first-file-name.png');
var mySecondFileContent = service.getAssetFileContent('my-second-file-name.json');
// ... use the file content happily ...
}
在 Flutter 包中,您要使用 pure-dart 包:void main() {
service = AssetFileFetcherService(); // or use other IoC methods such as the `GetIt` Dart package
myFunctionThatUsesAssetFile();
}
class AssetFileFetcherService extends AbstractAssetFileFetcherService {
String getAssetFileContent(String assetName) {
return rootBundle.loadString(assetName); // just use any normal method. you are in Flutter environment here.
}
}
编辑
Flutter 的 Assets 文件可能不存在于磁盘路径中的任何位置——例如,它可以压缩在 apk (android) 文件中。此外,您可能没有足够的权限这样做。
https://flutter.dev/docs/development/ui/assets-and-images#asset-bundling
During a build, Flutter places assets into a special archive called the asset bundle that apps read from at runtime.
关于json - 如何访问纯dart包中的 Assets 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67849867/