Android 12模拟器中Flutter camera插件takePicture方法无响应
Camera插件takePicture()方法阻塞无响应问题
环境信息
- camera插件版本:0.10.5+2
- 测试环境:Android 12 Pixel 6模拟器
问题现象
调用CameraController.takePicture()方法时,程序出现卡死或进入无限循环,后续代码无法执行,且无任何异常抛出。例如以下两个示例中,print('A picture was captured.')语句始终不会执行:
无状态组件示例
import 'package:flutter/material.dart'; import 'package:camera/camera.dart'; Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); final cameraController = CameraController( (await availableCameras())[0], ResolutionPreset.max, ); await cameraController.initialize(); final app = MaterialApp( home: CameraScreen( controller: cameraController, ), ); runApp(app); } class CameraScreen extends StatelessWidget { const CameraScreen({ super.key, required this.controller, }); final CameraController controller; Future<void> takePicture() async { await controller.takePicture(); // 此调用永远不会返回 print('A picture was captured.'); // 该行代码永远不会执行 } @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: Column( children: [ CameraPreview(controller), ElevatedButton( onPressed: takePicture, child: const Text('TAKE PICTURE'), ) ], ), ), ); } }
有状态组件示例
import 'package:flutter/material.dart'; import 'package:camera/camera.dart'; Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); final app = MaterialApp( home: CameraScreen( description: (await availableCameras())[0], ), ); runApp(app); } class CameraScreen extends StatefulWidget { const CameraScreen({ super.key, required this.description, }); final CameraDescription description; @override State<CameraScreen> createState() => _CameraScreenState(); } class _CameraScreenState extends State<CameraScreen> { late CameraController controller; Future<void> takePicture() async { await controller.takePicture(); // 此调用永远不会返回 print('A picture was captured.'); // 该行代码永远不会执行 } @override void initState() { controller = CameraController( widget.description, ResolutionPreset.max, ); if (controller.value.isInitialized == false) { controller.initialize(); } super.initState(); } @override void dispose() { controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: Column( children: [ CameraPreview(controller), ElevatedButton( onPressed: takePicture, child: const Text('TAKE PICTURE'), ) ], ), ), ); } }
解决方案
1. 确保相机完全初始化后再操作
有状态组件示例中,initState里的相机初始化未使用await,也未监听初始化状态,可能导致拍照时相机未就绪引发阻塞。修改初始化逻辑:
@override void initState() { super.initState(); controller = CameraController( widget.description, ResolutionPreset.max, ); _initCamera(); } Future<void> _initCamera() async { try { await controller.initialize(); if (mounted) setState(() {}); } catch (e) { print('相机初始化失败: $e'); } }
2. 给拍照方法添加状态检查与异常捕获
增加相机状态校验,防止重复调用,并捕获可能的异常:
Future<void> takePicture() async { if (!controller.value.isInitialized) { print('相机未初始化'); return; } if (controller.value.isTakingPicture) { return; // 避免重复触发拍照 } try { final XFile picture = await controller.takePicture(); print('照片已保存至: ${picture.path}'); } catch (e) { print('拍照失败: $e'); } }
3. 升级camera插件版本
0.10.5+2版本存在Android 12兼容性问题,建议升级至最新稳定版(如0.13.x及以上),新版本修复了多个平台适配bug。
4. 调整模拟器配置
- 在AVD管理器中,确保目标设备的相机功能已启用(进入设备的“Show Advanced Settings”,将Camera选项设置为“Emulated”或关联真实相机)
- 尝试降低分辨率预设,例如使用
ResolutionPreset.medium代替max,高分辨率在模拟器上易引发性能瓶颈
内容的提问来源于stack exchange,提问作者XUNIT
相关产品推荐
相关产品推荐

