studio including importar example defaulthttpclient clase android httpclient

importar - including apache http client on android studio



Android httpclient se cuelga en la segunda solicitud al servidor(se ha agotado el tiempo de conexión) (7)

Debido a que muchas de estas respuestas son antiguas y dependen del método consumeContent() , que ahora se redujo en gran consumeContent() , pensé que respondería con una alternativa al problema del tiempo de Timeout waiting for connection from pool .

HttpEntity someEntity = response.getEntity(); InputStream stream = someEntity.getContent(); BufferedReader rd = new BufferedReader(new InputStreamReader(stream)); StringBuffer result = new StringBuffer(); String line = ""; while ((line = rd.readLine()) != null) { result.append(line); } // On certain android OS levels / certain hardware, this is not enough. stream.close(); // This line is what is recommended in the documentation

Esto es lo que se muestra en la documentación:

cz.msebera.android.httpclient.HttpEntity @java.lang.Deprecated public abstract void consumeContent() throws java.io.IOException This method is deprecated since version 4.1. Please use standard java convention to ensure resource deallocation by calling InputStream.close() on the input stream returned by getContent()

Estoy teniendo problemas con el siguiente problema: Mi aplicación realiza una secuencia de solicitudes al servidor http utilizando HttpClient. Yo uso HttpPut para enviar datos al servidor. La primera solicitud va bien y es rápida, la segunda solicitud se cuelga durante 40 segundos y luego detecto la excepción de tiempo de espera de Connection. Estoy intentando reutilizar mi HttpClient y enviar una segunda solicitud a través de la misma instancia. Si creo un nuevo HttpClient junto con un nuevo ConnectionManager, entonces todo funciona bien.

¿Por qué está pasando esto? ¿Y cómo solucionarlo y no crear un nuevo HttpClient cada vez?

Gracias por adelantado.

Aquí está mi código: (si comento readClient = newHttpClient (readClient) en doPut, entonces surge el problema.

public class WebTest { private HttpClient readClient; private SchemeRegistry httpreg; private HttpParams params; private URI url; //http://my_site.net/data/ protected HttpClient newHttpClient(HttpClient oldClient) { if(oldClient != null) oldClient.getConnectionManager().shutdown(); ClientConnectionManager cm = new SingleClientConnManager(params, httpreg); return new DefaultHttpClient(cm, params); } protected String doPut(String data) { //**************************** //Every time we need to send data, we do new connection //with new ConnectionManager and close old one readClient = newHttpClient(readClient); //***************************** String responseS = null; HttpPut put = new HttpPut(url); try { HttpEntity entity = new StringEntity(data, "UTF-8"); put.setEntity(entity); put.setHeader("Content-Type", "application/json; charset=utf-8"); put.setHeader("Accept", "application/json"); put.setHeader("User-Agent", "Apache-HttpClient/WebTest"); responseS = readClient.execute(put, responseHandler); } catch(IOException exc) { //error handling here } return responseS; } public WebTest() { httpreg = new SchemeRegistry(); Scheme sch = new Scheme("http", PlainSocketFactory.getSocketFactory(), 80); httpreg.register(sch); params = new BasicHttpParams(); ConnPerRoute perRoute = new ConnPerRouteBean(10); ConnManagerParams.setMaxConnectionsPerRoute(params, perRoute); ConnManagerParams.setMaxTotalConnections(params, 50); ConnManagerParams.setTimeout(params, 15000); int timeoutConnection = 15000; HttpConnectionParams.setConnectionTimeout(params, timeoutConnection); // Set the default socket timeout (SO_TIMEOUT) // in milliseconds which is the timeout for waiting for data. int timeoutSocket = 40000; HttpConnectionParams.setSoTimeout(params, timeoutSocket); } private ResponseHandler<String> responseHandler = new ResponseHandler<String>() { @Override public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException { StatusLine statusLine = response.getStatusLine(); if (statusLine.getStatusCode() >= 300) { throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase()); } HttpEntity entity = response.getEntity(); if(entity == null) return null; InputStream instream = entity.getContent(); return this.toString(entity, instream, "UTF-8"); } public String toString( final HttpEntity entity, final InputStream instream, final String defaultCharset) throws IOException, ParseException { if (entity == null) { throw new IllegalArgumentException("HTTP entity may not be null"); } if (instream == null) { return null; } if (entity.getContentLength() > Integer.MAX_VALUE) { throw new IllegalArgumentException("HTTP entity too large to be buffered in memory"); } int i = (int)entity.getContentLength(); if (i < 0) { i = 4096; } String charset = EntityUtils.getContentCharSet(entity); if (charset == null) { charset = defaultCharset; } if (charset == null) { charset = HTTP.DEFAULT_CONTENT_CHARSET; } Reader reader = new InputStreamReader(instream, charset); StringBuilder buffer=new StringBuilder(i); try { char[] tmp = new char[1024]; int l; while((l = reader.read(tmp)) != -1) { buffer.append(tmp, 0, l); } } finally { reader.close(); } return buffer.toString(); } };

}


Es suficiente para la solución del problema (tuve el mismo):

EntityUtils.consume(response.getEntity());

Comprobación nula realizada dentro del consumo.


He tenido este mismo problema. Estoy consumiendo todo el contenido.

Lo que encontré es que si hago una recolección de basura después de emitir una solicitud, todo funciona sin tener que cerrar y crear un nuevo AndroidHttpClient:

System.gc ();


Parece que no consumes la entidad después de terminar de manejar la respuesta. Asegúrate de poner el siguiente código en el bloque finally :

if (httpEntity != null) { try { httpEntity.consumeContent(); } catch (IOException e) { Log.e(TAG, "", e); } }

Le sugiero que lea el tutorial de HttpClient .


Pensé que me gustaría elaborar sobre las otras respuestas. Experimenté este problema también. El problema fue porque no estaba consumiendo contenido.

Parece que si no lo hace, entonces la conexión se mantendrá y no podrá enviar una nueva solicitud con esta misma conexión. Para mí fue un error particularmente difícil de detectar ya que estaba usando el BasicResponseHandler proporcionado en Android. El código se ve así ...

public String handleResponse(final HttpResponse response) throws HttpResponseException, IOException { StatusLine statusLine = response.getStatusLine(); if (statusLine.getStatusCode() >= 300) { throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase()); } HttpEntity entity = response.getEntity(); return entity == null ? null : EntityUtils.toString(entity); }

Entonces, si hay una línea de estado por encima de 300, entonces no consumo el contenido. Y hubo contenido en mi caso. Hice mi propia clase como esta ...

public class StringHandler implements ResponseHandler<String>{ @Override public BufferedInputStream handleResponse(HttpResponse response) throws IOException { public String handleResponse(final HttpResponse response) throws HttpResponseException, IOException { StatusLine statusLine = response.getStatusLine(); HttpEntity entity = response.getEntity(); if (statusLine.getStatusCode() >= 300) { if (entity != null) { entity.consumeContent(); } throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase()); } return entity == null ? null : EntityUtils.toString(entity); } } }

Así que básicamente, en cualquier caso, consumir el contenido!


Suena extraño, pero tuve exactamente el mismo problema. La aplicación en la que estaba trabajando realizaba varias solicitudes sucesivas para descargar un grupo de imágenes en miniatura para mostrarlas en un ListView, y después de la segunda se bloqueaba como si hubiera un bloqueo en el código HttpClient.

La solución extraña que encontré fue usar AndroidHttpClient en lugar de DefaultHttpClient. Tan pronto como hice esto, y probé muchas cosas antes de seguir esta ruta, empezó a funcionar bien. Solo recuerda llamar a client.close () cuando hayas terminado con la solicitud.

AndroidHttpClient se describe en la documentación como DefaultHttpClient con "configuraciones predeterminadas razonables y esquemas registrados para Android". Dado que esto se introdujo en el nivel 8 de api (Android 2.2), desenterré la fuente para duplicar estas "configuraciones predeterminadas" para poder usarla más atrás que el nivel de api. Aquí está mi código para duplicar los valores predeterminados y una clase auxiliar con un método estático para cerrarlo de manera segura

public class HttpClientProvider { // Default connection and socket timeout of 60 seconds. Tweak to taste. private static final int SOCKET_OPERATION_TIMEOUT = 60 * 1000; public static DefaultHttpClient newInstance(String userAgent) { HttpParams params = new BasicHttpParams(); HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); HttpProtocolParams.setContentCharset(params, HTTP.DEFAULT_CONTENT_CHARSET); HttpProtocolParams.setUseExpectContinue(params, true); HttpConnectionParams.setStaleCheckingEnabled(params, false); HttpConnectionParams.setConnectionTimeout(params, SOCKET_OPERATION_TIMEOUT); HttpConnectionParams.setSoTimeout(params, SOCKET_OPERATION_TIMEOUT); HttpConnectionParams.setSocketBufferSize(params, 8192); SchemeRegistry schReg = new SchemeRegistry(); schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); schReg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg); DefaultHttpClient client = new DefaultHttpClient(conMgr, params); return client; } }

Y en otra clase ...

public static void safeClose(HttpClient client) { if(client != null && client.getConnectionManager() != null) { client.getConnectionManager().shutdown(); } }


Tengo el mismo problema, al ejecutar varias solicitudes en un bucle.

Puedes resolverlo leyendo todo response.getEntity() .