Flutter安卓模拟器加载localhost图片失败求助
解决Flutter安卓模拟器加载localhost HTTPS图片失败的问题
问题分析
你遇到的HandshakeException: WRONG_VERSION_NUMBER错误,本质是TLS握手版本不匹配或本地服务器HTTPS证书不可信导致的:
- 本地开发服务器的TLS配置版本(如过旧的TLS 1.0/1.1)不在Flutter客户端支持范围内
- 自签名证书未被安卓模拟器信任,触发证书校验失败
- 安卓9+默认禁止明文HTTP,若服务器实际是HTTP但你用了HTTPS协议,也会导致握手错误
可行解决方案
1. 改用HTTP协议访问(优先推荐开发环境)
如果本地服务器支持HTTP,直接把链接从https://改成http://:
CircleAvatar( radius: SizerUtil.deviceType == DeviceType.tablet ? 12.w : 13.w, backgroundColor: kSecondaryColor, backgroundImage: NetworkImage('http://10.0.2.2:37211/Files/Registeration/Images/42_30092022074513.jpg'), ),
同时需要解决安卓9+的明文HTTP限制:
- 在
android/app/src/main/AndroidManifest.xml的application标签中添加:android:usesCleartextTraffic="true" - 或者创建更严格的网络安全配置文件
android/app/src/main/res/xml/network_security_config.xml:
然后在<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true">10.0.2.2</domain> </domain-config> </network-security-config>AndroidManifest.xml的application标签中引用:android:networkSecurityConfig="@xml/network_security_config"
2. 修复本地服务器的HTTPS配置
- 确保服务器使用TLS 1.2或更高版本(Flutter客户端默认支持的最低版本)
- 为服务器配置可信证书:
- 开发环境可生成自签名证书,并手动安装到安卓模拟器中(设置→安全→加密与凭据→从存储安装)
- 生产环境使用正规CA颁发的证书
3. 开发环境临时禁用证书校验(仅限测试,禁止生产使用)
如果必须用HTTPS且不想配置证书,可以自定义ImageProvider忽略证书错误:
import 'dart:io'; import 'dart:typed_data'; import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; class UnsecureNetworkImage extends ImageProvider<NetworkImage> { final String url; UnsecureNetworkImage(this.url); @override Future<NetworkImage> obtainKey(ImageConfiguration configuration) { return SynchronousFuture<NetworkImage>(NetworkImage(url)); } @override ImageStreamCompleter loadImage(NetworkImage key, ImageDecoderCallback decode) { return MultiFrameImageStreamCompleter( codec: _loadAsync(key), scale: key.scale, debugLabel: key.url, informationCollector: () => [ DiagnosticsProperty<ImageProvider>('Image provider', this), DiagnosticsProperty<NetworkImage>('Image key', key), ], ); } Future<Codec> _loadAsync(NetworkImage key) async { final HttpClient client = HttpClient() ..badCertificateCallback = ((cert, host, port) => true); // 忽略证书错误 final Uri resolved = Uri.parse(key.url); final HttpClientRequest request = await client.getUrl(resolved); final HttpClientResponse response = await request.close(); if (response.statusCode != HttpStatus.ok) { throw Exception('HTTP请求失败,状态码: ${response.statusCode}'); } final Uint8List bytes = await consolidateHttpClientResponseBytes(response); if (bytes.isEmpty) { throw Exception('图片文件为空: ${resolved.path}'); } return await decode(bytes); } }
使用方式:
CircleAvatar( radius: SizerUtil.deviceType == DeviceType.tablet ? 12.w : 13.w, backgroundColor: kSecondaryColor, backgroundImage: UnsecureNetworkImage('https://10.0.2.2:37211/Files/Registeration/Images/42_30092022074513.jpg'), ),
4. 检查模拟器网络配置
- 关闭安卓模拟器的代理设置(设置→网络→代理→无)
- 确认
10.0.2.2能正确映射到本地主机:在模拟器浏览器中访问http://10.0.2.2:37211,看是否能正常打开服务器页面
内容的提问来源于stack exchange,提问作者HuA
相关产品推荐
相关产品推荐

