In firts time if work with this source code in my app ,there is no problem ,but if I switch off wifi and try to get some resource from web service my app throws exception with state : Leak Found ,i use the close method of httpclient ,but nothing changes,after day ot two work with this code throws exception.
Stack print:
10-17 16:42:00.524: ERROR/AndroidHttpClient(931): Leak found
10-17 16:42:00.524: ERROR/AndroidHttpClient(931): java.lang.IllegalStateException: AndroidHttpClient created and never closed
Code :
public String getRequest(String url, ArrayList<NameValuePair> nameValuePairs){
String resp = "";
HttpParams httpParameters = new BasicHttpParams();
HttpProtocolParams.setContentCharset(httpParameters, HTTP.UTF_8);
HttpProtocolParams.setHttpElementCharset(httpParameters, HTTP.UTF_8);
AndroidHttpClient httpclient = null;
try {
httpclient = AndroidHttpClient.newInstance("V");
httpclient.getParams().setParameter("http.protocol.content-charset", HTTP.UTF_8);
HttpPost httppost = new HttpPost(url);
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs,HTTP.UTF_8));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
InputStream instream = entity.getContent();
Reader reader = new InputStreamReader(instream, HTTP.UTF_8);
StringBuilder buffer = new StringBuilder("");
char[] tmp = new char[1024];
int l;
while ((l = reader.read(tmp)) != -1) {
buffer.append(tmp, 0, l);
}
reader.close();
resp = buffer.toString().replace(""", "\"");
Log.d("V", "RESPONSE:-----\n" + resp + "\n--------------");
} catch (IOException e){
Log.e("V IOException [Send Request]","IO Exception");
if((e != null) && (e.getMessage() != null)){
Log.e("V",e.getMessage().toString());
}
} catch (Exception e) {
Log.e("V Exception [Send Request]","Exception Requester");
if((e != null) && (e.getMessage() != null)){
Log.e("V",e.getMessage().toString());
}
}finally {
if (httpclient != null && httpclient.getConnectionManager() != null) {
httpclient.close();
httpclient = null;
}
}
return resp;
}
Try: httppost.abort(); at the end. Also, I dont think create a httpclient for each request is a good idea, I think is better create the http client as instance variable and reuse for each request.
I might recommend using EntityUtils class to do what you are doing rather than what you are trying to do though. It will take care most of the problems
Related
While trying to run a httppost at my client (Android application) side using the below code, but on my browser, i do receive just the JSON output of the expected data.
protected String doInBackground(String... params) {
DefaultHttpClient httpclient = new DefaultHttpClient(new BasicHttpParams());
HttpPost httppost = new HttpPost("http://192.168.43.229/thecee/mobile_app/the_lost.php");
// Depends on your web service
httppost.setHeader("Content-type", "application/json");
InputStream inputStream = null;
String result = null;
try {
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
inputStream = entity.getContent();
// json is UTF-8 by default
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
result = sb.toString();
Log.d("The Content", result);
} catch (Exception e) {
// Oops
}
finally{
try {
if (inputStream != null) inputStream.close();
} catch (Exception squish) {
}
}
return result;
}
I am getting the error message below while trying to parse it.
03-31 04:29:50.463 18871-19413/com.example.ji.thecce D/The Content:
http://www.w3.org/1999/xhtml'>
The request failed
Response Error.
Technical description:502 Bad Gateway - Response Error, a
bad response was received from another proxy server or the destination
origin server.
03-31 04:29:50.466 18871-18871/com.example.ji.thecce
W/System.err: org.json.JSONException: Value
I will sincerely appreciate your response.
Thanks for your time.
I've been stuck on this particular dilemma for some time, I have scoured the site and found some help, but not to my particular issue. I'm trying to connect to a website to extract JSON data from it. The host is what i'm not sure about:
DefaultHttpClient client = new DefaultHttpClient();
HttpHost targetHost = new HttpHost("www.wunderground.com", 80);
HttpGet httpGet = new HttpGet(urllink); // urllink is "api.wunderground.com/api/my_key/conditions/forecast/hourly/alerts/q/32256.json"
httpGet.setHeader("Accept", "application/json");
httpGet.setHeader("Content-type", "application/json");
HttpResponse response = client.execute(targetHost, httpGet);
HttpEntity entity = response.getEntity();
InputStream instream = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(instream));
StringBuilder stringBuilder = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
stringBuilder.append(line + "\n");
}
} catch (Exception e) {
// print stacktrace
return null;
} finally {
try {
instream.close();
} catch (Exception e) {
// print stacktrace
return null;
}
}
return stringBuilder.toString();
The host could either be www.wunderground.com or api.wunderground.com, but when I try either of them i get Unknown host exception.
I found the error. It was that I did not have the permission in the android manifest!
The call should be similar to:
http://api.wunderground.com/api/Your_Key/conditions/q/CA/San_Francisco.json
or as stated in the API,
GET http://api.wunderground.com/api/Your_Key/features/settings/q/query.format
I am receiving the below error message when I execute this code.
A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.:
I am unable to identify the resource leak in the below code. I'll be greatful if anyone point out what actually I am doing wrong.
HttpPost request = new HttpPost(url);
StringBuilder sb = new StringBuilder();
StringEntity entity = new StringEntity(jsonString);
entity.setContentType("application/json;charset=UTF-8");
entity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json;charset=UTF-8"));
request.setHeader("Accept", "application/json");
request.setEntity(entity);
HttpResponse response = null;
DefaultHttpClient httpclient = getHttpClientImpl();
BufferedReader reader = null;
InputStream in = null;
try {
response = httpclient.execute(request);
in = response.getEntity().getContent();
reader = new BufferedReader(new InputStreamReader(in));
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception se) {
Log.e("Exception", se + "");
throw se;
} finally {
if (in != null)
in.close();
if (reader != null)
reader.close();
if (client != null && client.getConnectionManager() != null) {
client.getConnectionManager().shutdown();
}
}
return sb.toString();
I don't really see any issues with that code, but I recommend closing all the idle connections in the pool.
public abstract void closeIdleConnections (long idletime, TimeUnit tunit)
Furthermore, there are some known issues with the DefaultHttpClient when not entirely configured correctly. I recommend using the AndroidHttpClient as an implementation of the HttpClient interface. Visit following documentation for the explanation:
http://developer.android.com/reference/android/net/http/AndroidHttpClient.html
I have the following code for make a post to an url an retrieve the response as a String. But I'd like to get also the HTTP response code (404,503, etc). Where can I recover it?
I've tried with the methods offered by the HttpReponse class but didn't find it.
Thanks
public static String post(String url, List<BasicNameValuePair> postvalues) {
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
if ((postvalues == null)) {
postvalues = new ArrayList<BasicNameValuePair>();
}
httppost.setEntity(new UrlEncodedFormEntity(postvalues, "UTF-8"));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
return requestToString(response);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private static String requestToString(HttpResponse response) {
String result = "";
try {
InputStream in = response.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder str = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
str.append(line + "\n");
}
in.close();
result = str.toString();
} catch (Exception ex) {
result = "Error";
}
return result;
}
You can modify your code like this:
//...
HttpResponse response = httpclient.execute(httppost);
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
//edit: there is already function for this
return EntityUtils.toString(response.getEntity(), "UTF-8");
} else {
//Houston we have a problem
//we should do something with bad http status
return null;
}
EDIT: just one more thing ...
instead of requestToString(..); you can use EntityUtils.toString(..);
Have you tried this?
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
response.getStatusLine().getStatusCode();
Have you tried the following?
response.getStatusLine().getStatusCode()
I'm sorry for a little duplication, here, here, but they say, that if you read the the last byte of the body of response and close the input stream. It is ready for another request. But look what I got here, and I always get this error when executing a new request.
Invalid use of SingleClientConnManager: connection still allocated
public String detectGooglePost(String text) throws SystemException {
List<NameValuePair> qParams = new ArrayList<NameValuePair>();
qParams.add(new BasicNameValuePair("key", key));
List<NameValuePair> bodyParams = new ArrayList<NameValuePair>();
bodyParams.add(new BasicNameValuePair("q", text));
HttpPost httpPost = new HttpPost(createURI(qParams));
httpPost.addHeader("X-HTTP-Method-Override", "GET");
try {
httpPost.setEntity(new UrlEncodedFormEntity(bodyParams));
} catch (UnsupportedEncodingException e) {
throw new SystemException("Problem when buidling Google request entity", e);
}
String language = getLanguage(httpPost);
return language;
}
private String getLanguage(HttpUriRequest request) throws SystemException {
HttpResponse response;
try {
response = httpclient.execute(request);
} catch (Exception e) {
throw new SystemException("Problem when executing Google request", e);
}
int sc = response.getStatusLine().getStatusCode();
if (sc != HttpStatus.SC_OK)
throw new SystemException("google status code : " + sc);
StringBuilder builder = getBuilder(response);
String language = processJson(builder.toString());
return language;
}
private StringBuilder getBuilder(HttpResponse response) throws SystemException {
HttpEntity entity = response.getEntity();
if (entity == null)
throw new SystemException("response entity null");
StringBuilder builder = new StringBuilder();
BufferedReader in = null;
String str;
try {
in = new BufferedReader(new InputStreamReader(entity.getContent()));
while ((str = in.readLine()) != null)
builder.append(str);
} catch (IOException e) {
throw new SystemException("Reading input stream of http google response entity problem", e);
} finally {
IOUtils.closeQuietly(in);
}
if (builder.length() == 0)
throw new SystemException("content stream of response entity empty has zero length");
return builder;
}
How should I release the connection ? The stream is read and closed. But still when detectGooglePost(text) method is called again (singleton HttpClient instance), it throws that error.
Man it must work, try this :
HttpResponse response;
String responseBody;
try {
response = httpclient.execute(request);
int sc = response.getStatusLine().getStatusCode();
if (sc != HttpStatus.SC_OK)
throw new SystemException("google status code : " + sc);
HttpEntity entity = response.getEntity();
if (entity == null)
throw new SystemException("response entity null");
responseBody = EntityUtils.toString(entity);
} catch (Exception e) {
request.abort();
throw new SystemException("Problem when executing Google request", e);
}