2012-04-09 5 views
0

У меня есть веб-сервис, основанный на php, который генерирует кучу данных в JSON. Я имею в виду пример данных 65 КБ здесь для обсуждения. 65 КБ не стоит много загружать. Я тестировал это на JavaScript (называя его AJAX), и потребовалось несколько миллисекунд, чтобы получить пакет данных. Я добавил коды на стороне сервера и андроид-клиента, который будет отмечать метку времени, по которой данные были отправлены и получены. К моему ужасу, его взятие 2 минут для симулятора Android для получения 65 КБ даже на localhostПроизводительность Android HTTP Connection

Вот что я использую для извлечения данных. Два класса: один для очереди HTTP-подключений и их запуск один за другим, используя потоки и другие для фактической отправки и приема данных и методов запуска обработчика.

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(); 
} 
} 

Эти коды называются как:

public void SendHTTPRequest(String function, List<NameValuePair> Data, Handler handler) 
{ 
    new HttpConnection(handler).post(this.getServerAddress() + "/service-endpoint.php?function="+function,Data); 
} 

ответ

1

Вы обрабатываете входной поток в String неэффективным способом. Вместо этого попробуйте использовать StringBuilder. Нечто подобное должно быть быстрее (и протестировать его на устройстве, если это возможно)

StringBuilder sb = new StringBuilder(); 
String line = null; 
while ((line = reader.readLine()) != null) { 
    sb.append(line + "\r\n"); 
} 

Я также рекомендую посмотреть на один из многочисленных способов разбора JSON в Android (JSON, GSON, Джексон JSON), вместо обрабатывая данные как String.

+0

Я сделаю это и дам вам знать. Кстати, проблема не в синтаксическом анализе, поскольку я отслеживал журналы timestamp при получении и отправке данных на обоих концах (клиент и сервер). Это может быть в строковом здании, как вы указали. спасибо человеку – kishu27

+0

это сработало. здорово. Благодарю. Теперь я получаю весь материал за 3 секунды. Я теперь сокращаю длину пакетов данных, чтобы еще больше ускорить их. – kishu27

+1

Не беспокойтесь. Также единственной причиной, по которой я рекомендовал библиотеки JSON, является то, что вы можете перейти от InputStream прямо к объекту, пропустив шаг, на котором вы полностью конвертируете в String. Мой личный фаворит - Джексон Джонсон, если производительность ключевая. – denizmveli