0

JSON で大量のデータを生成する PHP ベースの Web サービスがあります。ここでは、説明のために 65KB のデータ サンプルを参照しています。65KB ならダウンロードにそれほど時間はかかりません。これを JavaScript (AJAX で呼び出す) でテストしたところ、データのパケットを取得するのに数ミリ秒かかりました。データが送受信されたタイムスタンプをマークするコードをサーバー側と Android クライアントに追加しました。 恐ろしいことに、ローカルホストでも Android シミュレーターが 65KB を取得するのに 2 分かかります。

これが私がデータを取得するために使用しているものです。1 つは HTTP 接続をキューに入れ、スレッドを使用して 1 つずつ実行し、もう 1 つは実際にデータを送受信し、ハンドラーのメソッドをトリガーするための 2 つのクラスです。

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

1 に答える 1

1

非効率的な方法で入力ストリームを文字列に処理しています。代わりに StringBuilder を使用してみてください。このようなものはより高速になるはずです(可能であればデバイスでもテストしてください)

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

また、データを文字列として処理するのではなく、Android で JSON を解析する多くの方法 (JSON、GSON、Jackson JSON) のいずれかを調べることをお勧めします。

于 2012-04-10T01:03:54.640 に答える