Android HTTPClient sometimes slow connecting? - android

I seem to be having issues with the Android HTTPClient some times its super fast and other times it can take a good few seconds to return a result or says connection refused.
As a test I have tried different web hosts and direct IP also with no effect, testing is on a device connected via wifi.
The code is also running on a thread so not on the main thread.
The code i am using is as follows:
String strURL = "http://www.example.com/webservice/index.php";
List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>(2);
nameValuePairList.add(new BasicNameValuePair("command", "saveFave"));
nameValuePairList.add(new BasicNameValuePair("rid", strID));
HttpParams params = new BasicHttpParams();
params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
params.setParameter(CoreProtocolPNames.USER_AGENT, "AppName_Android");
DefaultHttpClient hc = new DefaultHttpClient(params);
HttpPost post = new HttpPost(strURL);
try {
post.setEntity(new UrlEncodedFormEntity(nameValuePairList));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
try {
hc.setRedirectHandler(null);
HttpResponse rp = hc.execute(post);
Log.d("Http Post Response:", rp.toString());
if (rp.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
jsonData = EntityUtils.toString(rp.getEntity(), HTTP.UTF_8);
Log.v(TAG, "JSON Response " + jsonData );
} catch (Exception e) {
Log.v(TAG, "error " + e.getMessage());
}

you should be able to tweek the timeouts in debug to throw errors so you can get more data on the cause...
this.config = RequestConfig.custom()
.setConnectTimeout(6 * 1000)
.setConnectionRequestTimeout(30 * 1000)
.setSocketTimeout(30 * 1000)
.build();

That is normal behaviour on networks. I see it every day. Sometimes the first connection is fast but mostly slow. The next request goes often faster but not always. It can go slower too. For speed there is no guarantee.

Related

Android server http Connection

My android app is connected to my server thorugh http connection.The server will close the connection after 10seconds . But in client side(android) i want to close the connection in 5 seconds neither i receive data or not from the server my android app must close the connection.
when I tried setsotimeout(5000) two things happens
1.The android app is sending request again and again for every 5000milliseconds.
2.It works well in the case when the server closes.
Suggest me some good logic
protected String doInBackground(Object[] params)
{
try
{
List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>(1);
nameValuePair.add(new BasicNameValuePair("carddata", "this " + "is " + "normal" + "transaction"));
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("http://127.0.0.1:8080/MyServletProject/DoubleMeServlet");
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePair));
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setSoTimeout(httpParameters, 5000);
httpPost.setParams(httpParameters);
HttpResponse response = httpClient.execute(httpPost);
Log.d("Http Post Response:", response.toString());
HttpEntity entity = response.getEntity();
dsds = EntityUtils.toString(entity);
} catch (Exception e)
{
if (e.toString().equals("java.net.SocketTimeoutException"))
{
dsds=e.toString();
}
If I was you, I would create a layer between by http client and my app. Every time a request is made, it restarts a 5000ms timer to kill the connection.

I have got Socket Timeout Exception but My data submitted on server too

I have got an prob with http post request i have set time out and on socket time out exception my data submitted on server successfully how i can restrict data to submitted on server my code is following
try{HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(
AppSettings.SERVICE_URL.POST_NEW_REGISTRATION);
HttpConnectionParams.setConnectionTimeout(
httpClient.getParams(), 5000);
HttpConnectionParams.setSoTimeout(httpClient.getParams(), 5000);
JSONObject jsonObject = new JSONObject();
jsonObject.put("agent_id", SharedPrefrence.getUserID());
httpPost.setEntity(new StringEntity(jsonObject.toString(),
"UTF-8"));
// Set up the header types needed to properly transfer JSON
httpPost.setHeader("Content-Type", "application/json");
httpPost.setHeader("Accept-Encoding", "application/json");
// Execute POST
//int getConnectionTimeout (HttpParams params);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity responseEntity = httpResponse.getEntity();
if (responseEntity != null) {
response = EntityUtils.toString(responseEntity);
} else {
response = "{'success':'FALSE'}";
}
} catch (ClientProtocolException e) {
response = "{'success':'FALSE'}";
progressDialog.cancel();
} catch (IOException e) {
response = "{'success':'FALSE','message':'Connection Time Out'}";
Log.d("Ex", e.toString());
Log.e("Ex", e.toString());
progressDialog.cancel();
} catch (JSONException e) {
response = "{'success':'FALSE','message':'JSON Parse Error'}";
progressDialog.cancel();
e.printStackTrace();
} catch (Exception e) {
response = "{'success':'FALSE'}";
progressDialog.cancel();
e.printStackTrace();
}
I think you are saying that you are getting a socket timeout exception even though the data is successfully received by the server?
If so, I think you may want to look at the value you are setting for the socket timeout - this appears to be 500ms in your code, which is quite short. It is quite possible that everything on the server side is working fine, but that the response is simply not getting to the client within 500ms.
A typical default is in the 6-10 seconds range, but it is really solution dependent so you may want to experiment. This blog post suggests some defaults for different scenarios and may be a useful reference:
http://dev.bizo.com/2013/04/sensible-defaults-for-apache-httpclient.html
probably your API call takes more than 500 ms, increase it and try again.

Android HttpPut to Django REST Framework - data not updating

Does anyone have advice on making PUT requests from Android to Django REST Framework? When I post the code below to my API endpoint, specifying the record to be updated (e.g. http://mydomain/api/26), I get a response with status code 200 and the json content of the targeted record, but none of the content has been updated by the request. In contrast, when I make what appears to be an identical request via Postman or via the browsable API, it works fine, giving me the 200 response and the updated json content. Similarly, I can make POST requests to the API using nearly identical Android code with no problem. Any ideas would be wonderful. Thanks.
public static HttpResponse putJsonString(String jsonString, String targetUrl, Context context){
HttpResponse result = null;
try {
HttpParams httpParameters = new BasicHttpParams();
int timeoutConnection = 3000;
HttpConnectionParams.setConnectionTimeout(httpParameters,
timeoutConnection);
int timeoutSocket = 3000;
HttpConnectionParams
.setSoTimeout(httpParameters, timeoutSocket);
DefaultHttpClient httpclient = new DefaultHttpClient(
httpParameters);
HttpPut httpPut = new HttpPut(targetUrl);
StringEntity se = new StringEntity(jsonString, "UTF-8");
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE,
"application/json"));
httpPut.setEntity(se);
httpPut.setHeader("Accept", "application/json");
httpPut.setHeader("Content-type", "application/json");
httpPut.setHeader("Authorization", "Token " + PropertyHolder.getUserKey());
Log.d("put", "put content: " + parseInputStream(context, httpPut.getEntity().getContent()));
result = httpclient.execute(httpPut);
} catch (UnsupportedEncodingException e) {
Util.logError(context, TAG, "error: " + e);
} catch (ClientProtocolException e) {
Util.logError(context, TAG, "error: " + e);
} catch (IOException e) {
Util.logError(context, TAG, "error: " + e);
}
return result;
}
The solution seems to be simpler than I thought: Make sure there is a trailing slash in the target URL. So http://mydomain/api/26/ instead of http://mydomain/api/26. This does not seem to matter when sending the PUT request from Postman, but from Android, omitting the trailing slash appears to cause the request to be redirected, and in the process it turns into a GET. I think the underlying issue is how the Apache HTTP client handles redirects, and it may be worthwhile to explicitly set this as well, but for now simply adding the slash does the trick.

Android service - data connection lost and can't restore

The background of my service: it implements LocationListener and in LocationManager instance (locMananager) registers for updates:
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
In onLocationChanged method it calls a method named recordTrace with a current location, which then calls getHttpResponse to send the location coordinates to a server. The latter method is as follows:
public InputStream getHttpResponse(String url, ArrayList<NameValuePair> params, int timeout) throws Exception {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, timeout);
httpClient.setParams(httpParams);
HttpPost post = new HttpPost(url);
if(params != null && !params.isEmpty()) {
try {
post.setEntity(new UrlEncodedFormEntity(params));
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "HttpPost.setEntity Error: " + e.getMessage());
lastError = "błąd HTTP";
}
}
CookieStore store = new BasicCookieStore();
if(localCookies != null && localCookies.size() > 0) {
for(int i = 0; i < localCookies.size(); i++) {
store.addCookie(localCookies.get(i));
}
}
HttpContext context = new BasicHttpContext();
context.setAttribute(ClientContext.COOKIE_STORE, store);
HttpResponse response = null;
HttpEntity entity = null;
InputStream content = null;
try {
response = httpClient.execute(post, context);
store = (CookieStore) context.getAttribute(ClientContext.COOKIE_STORE);
List<Cookie> cookies = store.getCookies();
if(cookies != null && cookies.size() > 0) {
localCookies = new ArrayList<BasicClientCookie>();
for(Cookie cookie : cookies) {
localCookies.add((BasicClientCookie) cookie);
}
}
entity = response.getEntity();
content = entity.getContent();
return content;
} catch (ClientProtocolException e) {
throw e;
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw e;
}
}
params is a NameValuePair with prepared data, timeout is set to 5000 (5 seconds). ArrayList localCookies holds cookies saved before, after successful logging in (to keep the session).
The problem is: when I loose a mobile signal (i.e. when I go to a subway) and restore it, I get IOException, which is unrecoverable unless I restart the phone.
Any help would be appreciated. I'm loosing my mind and going bald!
Thanks,
Peter.
EDIT
I've done some research. After the method getHttpResponse is invoked, I utilize InputStream returned by it, but don't close it after all. Do you thing that might be the issue? Is this possible that the operator breaks the connection and then establishes a new one, whereas my InputStream somehow "keeps" the former connection and produces the problems with data transfer?
I added a finally block where now the InputSTream is closed. However, since it's hard to cause the problem on demand (it doesn't happen regularly), I can't check if closing stream solves it.
After a few days of testing it seems I've found the solution. Calling 2 methods solves the issue:
close the InputStream returned by httpResponse.getEntity()
shutdown the connection by executing httpClient.getConnectionManager().shutdown()
Code snippet of a complete request and response handling:
String url = "www.someurl.com";
ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("login", "mylogin"));
params.add(new BasicNameValuePair("password", "mypassword"));
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
try {
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
InputStream content = httpEntity.getContent();
/*
* utilize content here...
*/
content.close(); // here's the point
httpClient.getConnectionManager().shutdown(); // the second important thing
}
catch (UnsupportedEncodingException e) {}
catch (ClientProtocolException e) {}
catch (IOException e) {}
I'm answering my own question since I've spent a lot of time on searching what's causing the problem and I think I can save somebody's time. After a few days the aplication is still working and doesn't break the connection.
Regards,
Peter.

Cancel AsyncTask when HTTPPost fails?

I'm trying to cancel my AsyncTask when connecting to the server fails. I tried cancel(), but the onPostExecute() method still gets called, instead of onCancelled().
This is what I have inside doInBackground():
protected String doInBackground(String... params) {
Log.i("ping", "doInBackground() started");
DefaultHttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 15000);
HttpResponse response;
HttpEntity entity;
try {
HttpPost post = new HttpPost("http://192.168.1.6/ping/login.php");
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("username", getEmail()));
nvps.add(new BasicNameValuePair("password", getPassword()));
post.setHeader("Content-Type", "application/x-www-form-urlencoded");
post.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
response = client.execute(post);
entity = response.getEntity();
InputStream iStream = entity.getContent();
read(iStream);
iStream.close();
if(entity != null)
entity.consumeContent();
Log.i("ping", "doInBackground() vervolgd");
} catch (Exception e) {
e.printStackTrace();
Log.e("tvsping", "Exception: " + e.getMessage());
cancel(true);
}
return null;
}
I'm trying to see what happens when the server can't be reached (I'm shutting it down, so there's no way my phone is getting any response) and I get IOException: the connection was reset.
Any ideas how I should check if the connection isn't made?
update
I solved this like Tanmay suggested, with a boolean. But I have another problem:
Every time doInBackground() is called it takes about three minutes to stop, when it can't find the servers. Everything is fine when it can reach the server, but I can't have this taking 3 minutes before the user is notified of anything (I could do a background process, but still a 3 minute wating bar is no good neither)
Any ideas what is wrong with my code? This can't be normal, right?
From doInBackground() method you are returning a String .You can return null if your HTTPPost fails.And then in onPostExecute() method just check what are you getting, if the String is null dont do anything which you really want and on successful running do your UI work
Hope this will help you.
HttpHost target = new HttpHost("192.168.2.3", 80);
HttpPost post = new HttpPost("/ping/login.php");
response = client.execute(target, post);
This solved the slow server response for me.

Categories

Resources