I have an application that posts to and gets from a PHP and MySQL server. I used this function all with GET actions but it took about 5 seconds. I used HttpParams but it didn't work, too.
Is there any way to make it faster?
String responseBine(){
Log.d("destpek wext","");
try{
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget= new HttpGet(urlIndex);
if(logged) {
HttpResponse rs = httpclient.execute(Teketin.httppost, localContext);
EntityUtils.toString(rs.getEntity());
rs = httpclient.execute(httpget, localContext);
EntityUtils.toString(rs.getEntity());
}
responseHandler = new BasicResponseHandler();
String rsp = new String(httpclient.execute(httpget, responseHandler).getBytes("ISO-8859-1"),"UTF-8");
return rsp;
}catch(Exception e){
System.out.println("Exception : " + e.getMessage());
}
Log.d("destpek wext","");
return "";
}
I was facing similar issues as yours until I discovered Volley(android library for http requests). Using Volley helped reducing some seconds.
Still not satisfied as my queries were taking about 2 to 3 seconds, I switched to Node.js + MySQL and it brought down the timing to around 200 milliseconds!
Related
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.
I know this has been asked a few times here but I've used every method on here and read everything I can think to read but I'm still having issues. I've even used a couple libraries including this one (https://github.com/koush/ion) to no avail.
I'm using a godaddy shared hosting plan. Sometimes it's very quick to execute my commands and other times it takes quite some time. Last try took 9 seconds but then I have others which are less than a second.
The biggest issue however is uploading an image just doesn't work. I have the same app doing the same thing in iOS and it uploads to the godaddy server and my exact same code works on mamp in Android but stops once it's taken live which rules out a code issue in my books.
iOS is always fast and consistent using the same server, however, Android varies from fast to a crawl, what's up?
My current method looks like this
public String postData(String url, List<NameValuePair> nameValuePairs) {
try {
HttpPost httppost = new HttpPost(url);
HttpParams params = new BasicHttpParams();
httppost.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
HttpClient httpclient = new DefaultHttpClient(params);
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse httpResponse = httpclient.execute(httppost);
HttpEntity responseEntity = httpResponse.getEntity();
if(responseEntity!=null) {
return EntityUtils.toString(responseEntity);
}
} catch (ClientProtocolException e) {
} catch (IOException e) {
}
return null;
}
I'm experiencing some odd behavior in my HTTP requests. I have some users that are saying that this call isn't ever coming back (the spinner marking it's asynchronous call never goes away). I have seen this happen before, but I attributed it to the emulator going through Charles Proxy. I haven't yet seen it on actual phone until now.
I'm not sure what would cause this to happen, which is why I'm posting it here. Here's the call, using Jackson to deserialize the result into a Value Object. The two spots I saw the emulator freeze are httpclient.execute(httpGet); and getObjectMapper().readValue(jp, SyncVO.class);.
While debugging, stepping over the offending statement caused the debugger to never gain control back of stepping. Meanwhile, I see the request go out AND come back from the server through Charles. It's just that the app doesn't seem to get the response and just sits there.
So, here's the code. Thanks for any help!
public SyncVO sync(String userId, long lastUpdate, boolean includeFetch) throws IOException {
SyncVO result = null;
String url = BASE_URL + "users/" + userId + "/sync" + "?" + "fetch=" + includeFetch;
if (lastUpdate > 0) {
url += "&updatedSince=" + lastUpdate;
}
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("Accept", "application/json");
httpGet.setHeader("Accept-Encoding", "gzip");
httpGet.setHeader(AUTHORIZATION, BEARER + " " + mOAuthToken);
httpclient.getParams().setParameter(CoreProtocolPNames.USER_AGENT, USER_AGENT_STRING);
httpclient.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
HttpResponse response = httpclient.execute(httpGet);
if (isUnauthorized(response)) {
APPLICATION.needReauthentication();
return null;
}
if (response != null) {
InputStream stream = response.getEntity().getContent();
Header contentEncoding = response.getFirstHeader("Content-Encoding");
if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip")) {
stream = new GZIPInputStream(stream);
}
InputStreamReader inReader = new InputStreamReader(stream, "UTF-8");
JsonParser jp = mJsonFactory.createJsonParser(inReader);
result = getObjectMapper().readValue(jp, SyncVO.class);
}
return result;
}
private ObjectMapper getObjectMapper() {
return (new ObjectMapper()
.configure(Feature.AUTO_DETECT_FIELDS, true)
.configure(Feature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true));
}
don't forget to consume entities content after each request.
HttpEntity entity = response.getEntity();
try {
if (entity != null)
entity.consumeContent();
} catch (IOException e) {
e.printStackTrace();
}
You should definitely use connection timeout and socket read and be prepared for the worst from the server. Network operations will never be 100% predictable and there is not much your client can do then so make sure you code optimally.
httpParameters = httpclient.getParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, 5000);
HttpConnectionParams.setSoTimeout(httpParameters, 10000);
You can also cancel a task with asyncTask.cancel(true);
The reason is because you have left stream open. As such, the response is left in limbo. This means your global variable httpClient is also left in limbo, and unable to get a new entity when it re-uses the client.
You should call close() after finishing with the stream.
stream.close();
Network calls take a while and will block the UI thread. Same with your jackson deserialization code. This stuff needs to be put on a separate thread. See AsyncTask for an easy way to do it.
In my Android application, i'm using ksoap2 library for consuming a soap ( & .net) webservice. It works correctly but it's very slow (for parsing, controls, loops and Base64ToBinary processes). I want to parse it more fast. Is it possible to parse it without using ksoap2? Any ideas?
Thanks for your recommendations.
What do you mean slow? It does a http request and then parses the response. You have to do this in an async task. Memory usage will depend on the response you get. Maybe you are requesting way too much. See the wiki on how to debug!
I have another problem with KSoap2. Unfortunately, ksoap2 library is not working with my webservices. So at last, I have done with default http post.
I hope this will help for someone in future.
private String makeHttpRequest(){
try{
String request = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns1=\"http://tempuri.org/\">"
+"<SOAP-ENV:Body>"
+ "<ns1:Connect>"
+ "<ns1:lstr_Login>xxxxx</ns1:lstr_Login>"
+"</ns1:Connect>"
+"</SOAP-ENV:Body>"
+"</SOAP-ENV:Envelope>";
String soapAction = "http://tempuri.org/Connect"; //this would be your soapAction from wsdl
StringEntity se = new StringEntity(request, HTTP.UTF_8);
DefaultHttpClient client = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(new URI("http://xxxxxxxx.com/Storefront.asmx"));
httpPost.addHeader("Content-Type", "text/xml; charset=utf-8");
httpPost.addHeader("SOAPAction", soapAction);
httpPost.setEntity(se);
HttpResponse response = client.execute(httpPost);
int responseStatusCode = response.getStatusLine().getStatusCode();
Log.d(TAG, "HTTP Status code:"+responseStatusCode);
if(responseStatusCode>=200 && responseStatusCode<300){
//we got the success response from server. Now retrieve the value and go for usage.
String responseStr = EntityUtils.toString(response.getEntity());
//use this responseStr to parse with pullparsers or any
Log.d("Response", "Response:: "+ responseStr);
return responseStr;
}
}catch(Exception e){
//Write the proper catch blocks for exceptions
Log.e("Response Exception" , e.getMessage()+"",e);
}
return null;
}
I'm developing an Android app that gets a JSON_encoded result from a php middleware script that connects to a MySQL database. I have given the application Internet permissions.
The problem I'm having is that the program gives an UnknownHostException error the first time it is run. I have the program on a timer, and subsequent calls to the timer handler function do not return the UnknownHostException error. Do you have any idea why this would occur? I have tested the domain and made sure that it connects correctly through a web browser.
Here's a snippet from the code:
public final void timerAlert(){
final Handler handler = new Handler();
final Runnable r = new Runnable()
{
public void run() {
Timer_Method();
handler.postDelayed(this,1000);
}
};
handler.postDelayed(r, 1000);
}
public void Timer_Method()
{
//See if this buzzer is being signaled.
String result = null;
InputStream is = null;
StringBuilder sb=null;
//http post
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("BuzzerID",BuzzerID.toString()));
Toast.makeText(getBaseContext(), "BuzzerID="+BuzzerID.toString() ,Toast.LENGTH_LONG).show();
try{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://domain/getBuzzStatus.php?BuzzerID="+BuzzerID.toString());
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
}catch(Exception e){
Log.e("log_tag", "Error in http connection"+e.toString());
Toast.makeText(getBaseContext(), "Hm, problem here="+e.toString() ,Toast.LENGTH_LONG).show();
}
Note that domain has something else there in the actual code and that this is just a snippet but is where the first issue occurs. Also note that I am mixing get and post, something I'd rather not do, but for some reason passing the nameValuePair to the php script doesn't send anything to $_REQUEST.
A snippet from the very simple PHP script:
$sql_string="SELECT Signal FROM BuzzCustomer WHERE idBuzzCustomer=" . $_GET['BuzzerID'];
$sql = mysql_query($sql_string);
while($row=mysql_fetch_assoc($sql))
$output[]=$row;
print(json_encode($output));
mysql_close();
I switched to $_GET here because I could not get $_REQUEST to work. Any help would be appreciated. Thanks in advance!
May be their will be no Internet connection in the simulator......Check a url in browser
Instead of
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
Use
ResponseHandler<String> response = new BasicResponseHandler();
String result = httpclient.execute(httppost,response);
Also put Internet permission in the Manifest
Just a guess, but maybe the DNS request takes too long and your HttpClient gives up, but the request is finished and cached so the next time it does not fail?
This With Apache HttpClient, why isn't my connection timeout working? seems to be a question about how to set the timeout for HttpClient.