Issue
I have a php based web service that churns out a heap of data in JSON. I am referring to a data sample of 65KB here for the sake of discussion. 65KB shouldn't take much to download. I tested this on a JavaScript (calling it by AJAX) and it took some milliseconds to fetch the packet of data. I have added codes on server side and android client that will mark the timestamp at which data was sent and received. To my horror, its taking 2 minutes for the Android simulator to fetch 65KB even on localhost
Here's what I am using to fetch data. Two classes, one for Queuing the HTTP Connections and run them one by one using threads and other for actually sending and receiving data and triggering methods of a handler.
HTTPConnection.java:
public class HttpConnection implements Runnable
{
public static final int DID_START = 0;
public static final int DID_ERROR = 1;
public static final int DID_SUCCEED = 2;
private static final int GET = 0;
private static final int POST = 1;
private static final int PUT = 2;
private static final int DELETE = 3;
private static final int BITMAP = 4;
private String url;
private int method;
private Handler handler;
private List<NameValuePair> postData;
private String data;
private HttpClient httpClient;
public HttpConnection()
{
this(new Handler());
}
public HttpConnection(Handler _handler)
{
handler = _handler;
}
public void create(int method, String url, String data)
{
this.method = method;
this.url = url;
this.data = data;
ConnectionManager.getInstance().push(this);
}
public void createPost(int method, String url, List<NameValuePair>data)
{
this.method = method;
this.url = url;
this.postData = data;
ConnectionManager.getInstance().push(this);
}
public void get(String url)
{
create(GET, url, null);
}
public void post(String url, List<NameValuePair> data)
{
createPost(POST, url, data);
}
public void put(String url, String data)
{
create(PUT, url, data);
}
public void delete(String url)
{
create(DELETE, url, null);
}
public void bitmap(String url)
{
create(BITMAP, url, null);
}
public void run()
{
handler.sendMessage(Message.obtain(handler, HttpConnection.DID_START));
httpClient = new DefaultHttpClient();
HttpConnectionParams.setSoTimeout(httpClient.getParams(), 10000);
try {
HttpResponse response = null;
switch (method) {
case GET:
response = httpClient.execute(new HttpGet(url));
break;
case POST:
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(postData));
response = httpClient.execute(httpPost);
break;
case PUT:
HttpPut httpPut = new HttpPut(url);
httpPut.setEntity(new StringEntity(data));
response = httpClient.execute(httpPut);
break;
case DELETE:
response = httpClient.execute(new HttpDelete(url));
break;
case BITMAP:
response = httpClient.execute(new HttpGet(url));
processBitmapEntity(response.getEntity());
break;
}
if (method < BITMAP)
processEntity(response.getEntity());
} catch (Exception e) {
handler.sendMessage(Message.obtain(handler,
HttpConnection.DID_ERROR, e));
}
ConnectionManager.getInstance().didComplete(this);
}
private void processEntity(HttpEntity entity) throws IllegalStateException,IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(entity.getContent()));
String line, result = "";
while ((line = br.readLine()) != null)
result += line;
Message message = Message.obtain(handler, DID_SUCCEED, result);
handler.sendMessage(message);
}
private void processBitmapEntity(HttpEntity entity) throws IOException
{
BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(entity);
Bitmap bm = BitmapFactory.decodeStream(bufHttpEntity.getContent());
handler.sendMessage(Message.obtain(handler, DID_SUCCEED, bm));
}
}
ConnectionManager.java:
public class ConnectionManager
{
public static final int MAX_CONNECTIONS = 5;
private ArrayList<Runnable> active = new ArrayList<Runnable>();
private ArrayList<Runnable> queue = new ArrayList<Runnable>();
private static ConnectionManager instance;
public static ConnectionManager getInstance()
{
if (instance == null)
instance = new ConnectionManager();
return instance;
}
public void push(Runnable runnable)
{
queue.add(runnable);
if (active.size() < MAX_CONNECTIONS)
startNext();
}
private void startNext()
{
if (!queue.isEmpty())
{
Runnable next = queue.get(0);
queue.remove(0);
active.add(next);
Thread thread = new Thread(next);
thread.start();
}
}
public void didComplete(Runnable runnable)
{
active.remove(runnable);
startNext();
}
}
These codes are called like:
public void SendHTTPRequest(String function, List<NameValuePair> Data, Handler handler)
{
new HttpConnection(handler).post(this.getServerAddress() + "/service-endpoint.php?function="+function,Data);
}
Solution
You are processing the input stream into a String in an inefficient way. Try using a StringBuilder instead. Something like this should be faster (also test it on a device if possible)
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\r\n");
}
I'd also recommend looking into one of the many ways to parse JSON in Android (JSON, GSON, Jackson JSON) instead of processing the data as a String.
Answered By - denizmveli
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.