Android加载PHP后端GIF出现GifError 103等报错如何解决
问题原因
- GifIOException: GifError 103 核心原因:你先调用了
BitmapFactory.decodeStream(inputStream)读取了整个输入流,流指针已经移动到末尾,后续inputStreamTOByte读取到的是空/不完整数据,不符合GIF格式规范。 - IllegalArgumentException: InputStream does not support marking 核心原因:HttpURLConnection返回的原生InputStream不支持mark/reset操作,而
android-gif-drawable直接解析InputStream时需要依赖mark操作来回溯GIF头信息,因此抛出异常。
修复方案
1. 修复Android端流读取逻辑
不要重复读取同一个InputStream,优先将流一次性转成字节数组,再基于字节数组生成所需的Bitmap和GifDrawable,示例代码如下:
// 先把InputStream转成字节数组,只读取一次原流 byte[] gifBytes = inputStreamTOByte(inputStream); inputStream.close(); // 如果需要Bitmap,用字节数组生成 Bitmap img = BitmapFactory.decodeByteArray(gifBytes, 0, gifBytes.length); // 直接用字节数组生成GifDrawable,不会触发mark相关异常 GifDrawable gif = new GifDrawable(gifBytes); ivProfileImage.setImageDrawable(gif);
如果你不需要Bitmap,也可以给原InputStream套一层BufferedInputStream直接传入GifDrawable:
BufferedInputStream bufferedIs = new BufferedInputStream(inputStream); bufferedIs.mark(bufferedIs.available()); GifDrawable gif = new GifDrawable(bufferedIs); ivProfileImage.setImageDrawable(gif); bufferedIs.close();
2. 修复PHP后端冗余代码
删除重复的Content-Disposition声明,避免部分客户端解析响应头异常,也可以固定Content-Type为image/gif排除MIME识别错误问题:
header($_SERVER["SERVER_PROTOCOL"] . " 200 OK"); header("Cache-Control: public"); // 固定Content-Type测试,确认mime_content_type返回值正确的话也可以保留原有逻辑 header("Content-Type: image/gif"); header("Content-Transfer-Encoding: Binary"); header("Content-Length:" . filesize($attachment_location)); // 删除重复的那行Content-Disposition,只保留带filename的 header('Content-Disposition: attachment; filename="' . $fileName . '"'); readfile($attachment_location); exit;
3. 非必要优化项
Android端请求头中Access-Control-Allow-Origin、Access-Control-Allow-Methods、Access-Control-Allow-Headers属于响应头,不需要在请求中添加,可以直接删除。
内容的提问来源于stack exchange,提问作者JO Developer
相关产品推荐
相关产品推荐

