使用advance_pdf_viewer加载Firebase存储PDF时模拟器崩溃报错
从Firebase Storage获取PDF文件列表后,使用advance_pdf_viewer插件查看PDF,传递文件给阅读器时模拟器立即崩溃,出现以下错误日志:
E/AndroidRuntime(31096): java.lang.IllegalStateException: Reply already submitted
E/AndroidRuntime(31096): at io.flutter.embedding.engine.dart.DartMessenger$Reply.reply(DartMessenger.java:430)
E/AndroidRuntime(31096): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler$1.success(MethodChannel.java:267)
E/AndroidRuntime(31096): at pt.tribeiro.flutter_plugin_pdf_viewer.FlutterPluginPdfViewerPlugin$1$2.run(FlutterPluginPdfViewerPlugin.java:92)
E/AndroidRuntime(31096): at android.os.Handler.handleCallback(Handler.java:873)
E/AndroidRuntime(31096): at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(31096): at android.os.Looper.loop(Looper.java:214)
E/AndroidRuntime(31096): at android.app.ActivityThread.main(ActivityThread.java:7073)
E/AndroidRuntime(31096): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(31096): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
E/AndroidRuntime(31096): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)
E/flutter (31096): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: MissingPluginException(No implementation found for method getPage on channel flutter_plugin_pdf_viewer)
相关代码如下:
class FilePage extends Stateful Widget { const FilePage({required this.file, this.isImage = false}); final FirebaseFile file; final isImage; @override _FilePageState createState() => _FilePageState(); } class _FilePageState extends State<FilePage> { @override void initState() { super.initState(); } @override Widget build(BuildContext context) { //initState(){ return WillPopScope( onWillPop: () async => true, child: Scaffold( appBar: AppBar( backgroundColor: Colors.indigo[900], title: Text(widget.file.name.split('.').first), centerTitle: true, ), body: widget.isImage ? loadImage(widget.file.url) : FutureBuilder( future: PDFDocument.fromURL(widget.file.url), builder: (context, snapshot) { switch (snapshot.connectionState) { case ConnectionState.waiting: case ConnectionState.active: return Center( child: CircularProgressIndicator(), ); default: var pdf = snapshot.data as PDFDocument; return PDFViewer(document: pdf); } }), ), ); } Widget loadImage(String url) { return Image.network( url, loadingBuilder: (context, widget, event) { if (event == null) return widget; return Center( child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ CircularProgressIndicator(), SizedBox( height: 20, ), Text('Loading') ], ), ); }, ); } }
1. 修复FutureBuilder重复执行问题
将PDFDocument.fromURL的调用从build方法移到initState中,避免每次组件重建时重复发起PDF加载请求,导致插件方法通道重复回调:
class _FilePageState extends State<FilePage> { Future<PDFDocument>? _pdfFuture; @override void initState() { super.initState(); if (!widget.isImage) { _pdfFuture = PDFDocument.fromURL(widget.file.url); } } @override Widget build(BuildContext context) { return WillPopScope( onWillPop: () async => true, child: Scaffold( appBar: AppBar( backgroundColor: Colors.indigo[900], title: Text(widget.file.name.split('.').first), centerTitle: true, ), body: widget.isImage ? loadImage(widget.file.url) : FutureBuilder( future: _pdfFuture, builder: (context, snapshot) { switch (snapshot.connectionState) { case ConnectionState.waiting: case ConnectionState.active: return Center(child: CircularProgressIndicator()); case ConnectionState.done: if (snapshot.hasError) { return Center(child: Text('加载PDF失败: ${snapshot.error}')); } var pdf = snapshot.data as PDFDocument; return PDFViewer(document: pdf); default: return Center(child: Text('未知状态')); } }), ), ); } // loadImage方法保持不变 }
2. 处理插件兼容性问题
- 检查
advance_pdf_viewer版本,若使用旧版本,尝试升级到最新稳定版;该插件底层依赖的flutter_plugin_pdf_viewer存在方法通道重复提交的bug,也可以考虑替换为维护更活跃的PDF插件(如pdfx)。 - 执行
flutter clean和flutter pub get清理项目缓存,重新构建确保插件正确集成。
3. 验证文件访问权限
确认Firebase Storage中的PDF文件有公开访问权限,或应用已通过身份验证获取到有效访问URL,避免因URL无效、权限不足导致加载失败,间接触发插件错误。
内容的提问来源于stack exchange,提问作者learner

