Android: ThreadSafeClientConnManager 下载图片的错误

对于我当前的应用程序,我从西班牙的不同“事件提供商”收集图像。

  Bitmap bmp=null;
  HttpGet httpRequest = new HttpGet(strURL);

  long t = System.currentTimeMillis();
  HttpResponse response = (HttpResponse) httpclient.execute(httpRequest);
  Log.i(TAG, "Image ["+ strURL + "] fetched in [" + (System.currentTimeMillis()-t) + "ms]");

     HttpEntity entity = response.getEntity();
     InputStream instream = entity.getContent();
     bmp = BitmapFactory.decodeStream(instream);

     return bmp;

但是,从 salir.com 下载图像时,我得到以下logcat输出:

13970     Gallery_Activity  I  Fetching image 2/8 URL: http://media.salir.com/_images_/verticales/a/0/1/0/2540-los_inmortales_la_trattoria-marc_aureli_27_29_no.jpg
13970     ServiceHttpRequest  I  Image [http://media.salir.com/_images_/verticales/a/0/1/0/2540-los_inmortales_la_trattoria-marc_aureli_27_29_no.jpg] fetched in [146ms]
13970     skia  D  --- decoder->decode returned false

搜索该错误消息并未提供太多有用的结果。

有人知道问题可能是什么吗?

谢谢!


更新 1:

在询问了更多内容并测试了不同的东西之后,我发现问题似乎出在其他地方。即使我的logcat输出说

13970     ServiceHttpRequest  I  Image [http://media.salir.com/_images_/verticales/a/0/1/0/2540-los_inmortales_la_trattoria-marc_aureli_27_29_no.jpg] fetched in [146ms]
getContentLength(): 93288

这是图像的正确长度(以字节为单位),似乎流或HTTP连接有问题。

我的原始代码(上图)正在利用ThreadSafeClientConnManager。如果我用一个简单的词替换它,它就能完美地工作:URLConnection

URL url = new URL(strURL);
URLConnection conn = url.openConnection();
conn.connect();
InputStream instream = conn.getInputStream();
bmp = BitmapFactory.decodeStream(instream);

所以,我现在想知道为什么我的工作与我所有其他联系(主要是交换)完美无缺(至少看起来是这样),而不是来自某些特定网站的图像(例如 salir.com - 对于大多数其他网站来说,它的工作原理,虽然)。是否有我缺少的 HTTP 参数?ThreadSafeClientConnManagerJSONObjects

我目前的设置是:

HttpParams parameters = new BasicHttpParams();
HttpProtocolParams.setVersion(parameters, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(parameters, HTTP.UTF_8);
HttpProtocolParams.setUseExpectContinue(parameters, false); // some webservers have problems if this is set to true
ConnManagerParams.setMaxTotalConnections(parameters, MAX_TOTAL_CONNECTIONS);
HttpConnectionParams.setConnectionTimeout(parameters, CONNECTION_TIMEOUT);
HttpConnectionParams.setSoTimeout(parameters, SOCKET_TIMEOUT);

SchemeRegistry schReg = new SchemeRegistry();
schReg.register(new Scheme("http", 
     PlainSocketFactory.getSocketFactory(), HTTP_PORT));

ClientConnectionManager conMgr = new ThreadSafeClientConnManager(parameters,schReg);

DefaultHttpClient http_client = new DefaultHttpClient(conMgr, parameters);

更新 2:

现在,奇怪的是,它实际上确实与 -有时 - 一起工作。如果我一直尝试下载图像并连续几次解码它,它可能会在15-30次试用后工作。很奇怪。ThreadSafeClientConnManager

我希望有一个解决方案,因为我更喜欢使用而不是.ThreadSafeClientConnManagerURLConnection


更新 3:

正如Mike Mosher在下面所建议的那样,通过使用BufferedHttpEntity,解码错误似乎不再出现。然而现在,即使比以前更少,我也得到了一个错误。SkImageDecoder::Factory returned null


答案 1

斯特凡

我遇到了同样的问题,并没有在互联网上找到太多的搜索。很多人都有这个问题,但没有很多答案来解决它。

我正在使用URLConnection获取图像,但我发现问题不在于下载,但是BitmapFactory.decodeStream在解码图像时遇到了问题。

我更改了我的代码以反映您的原始代码(使用httpRequest)。我做了一个改变,我在 http://groups.google.com/group/android-developers/browse_thread/thread/171b8bf35dbbed96/c3ec5f45436ceec8?lnk=raot 找到了(感谢Nilesh)。您需要添加“BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(entity);”

这是我之前的代码:

        conn = (HttpURLConnection) bitmapUrl.openConnection(); 
        conn.connect();
        is = conn.getInputStream();
        //bis = new BufferedInputStream(is);
        //bm = BitmapFactory.decodeStream(bis);
        bm = BitmapFactory.decodeStream(is);

而她就是有效的代码:

            HttpGet httpRequest = null;

    try {
        httpRequest = new HttpGet(bitmapUrl.toURI());
    } catch (URISyntaxException e) {
        e.printStackTrace();
    }

    HttpClient httpclient = new DefaultHttpClient();
        HttpResponse response = (HttpResponse) httpclient.execute(httpRequest);

        HttpEntity entity = response.getEntity();
        BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(entity); 
        InputStream instream = bufHttpEntity.getContent();
        bm = BitmapFactory.decodeStream(instream);

正如我所说,我有一个页面,可以下载大约40张图片,您可以刷新以查看最近的照片。我几乎有一半失败“解码器>解码返回错误错误”。使用上面的代码,我没有遇到任何问题。

谢谢


答案 2

我的解决方案不是使用因为我看待它的方式,它使用SKIA解码器,有时看起来有点不稳定。你可以试试这样的东西。BitmapFactory.decodeStream()

    Bitmap bitmap = null;
    InputStream in = null;
    BufferedOutputStream out = null;
    try {
            in = new BufferedInputStream(new URL(url).openStream(),
                     IO_BUFFER_SIZE);

            final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
            out = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE);
            copy(in, out);
            out.flush();

            final byte[] data = dataStream.toByteArray();
            bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);


   } catch (......){

   }        

和 copy() 函数

private static void copy(InputStream in, OutputStream out) throws IOException {
    byte[] b = new byte[IO_BUFFER_SIZE];
    int read;
    while ((read = in.read(b)) != -1) {
        out.write(b, 0, read);
    }
}

并且是值为 4 * 1024 的常量整数。IO_BUFFER_SIZE


推荐