Как получить данные JSON порциями для отчета о прогрессе? - PullRequest
7 голосов
/ 15 июля 2011

Мне нужно загрузить контактные данные через REST API, который я получаю в формате JSON. Проблема в том, что это может быть много контактов, поэтому я хочу наблюдать за прогрессом (сколько контактов уже загружено) и отчитываться перед пользователем (с индикатором выполнения, приведенный ниже код выполняется в потоке).

Однако, похоже, что строка client.execute (getRequest); устанавливает соединение и загружает весь контент за один раз, то есть мой считыватель InputStream (для извлечения содержимого в виде кусков) кажется бесполезным. Теперь мне интересно, как заставить его работать кусками, чтобы я мог сообщать о прогрессе?

/** prepare HTML get request */
HttpGet getRequest = new HttpGet(url[0]);
getRequest.addHeader("Authorization", "OAuth " + myTokens.get_access_token());

/** execute HTML request */
DefaultHttpClient client = new DefaultHttpClient();
JSONArray records = null;
HttpResponse response = client.execute(getRequest);

/** init response handlers for input stream */
InputStream input = new BufferedInputStream(response.getEntity().getContent());

byte data[] = new byte[MAX_BUFFER_SIZE];

long totalContactsCount = -1;
int readContactsCount = 0;
int currentByteReadCount = 0;

/** read response from inpus stream */
while ((currentByteReadCount = input.read(data)) != -1) {
    String readData = new String(data, 0, currentByteReadCount);
    dataString.append(readData);

    // then +1 progress on every ...},{... (JSON object separator)
    if (readData.indexOf("},{") >= 0) {
        readContactsCount++;
    }

    // publishing the progress....
    if (totalContactsCount > 0) {
        publishProgress((int)(readContactsCount * 100 / totalContactsCount));
    }
}
input.close();

/** transform response into JSONArray */
String result = dataString.toString();

//... convert into JSONArray

Ответы [ 3 ]

2 голосов
/ 15 июля 2011

К сожалению, как видно из документации по DefaultHttpClient, метод execute возвращает HTTP-ответ, уже проанализированный и, следовательно, уже считанный из сети, поэтому вы не можете подключить входной поток. Этот поток подготовлен для вас, чтобы быть прочитанным, но как только он был восстановлен, как вы заметили. Вы должны использовать другую стратегию. Например, попробуйте установить соединение с помощью API сокетов.

1 голос
/ 15 июля 2011

Возможно, вы захотите взглянуть на эту ветку stackoverflow , где был задан похожий вопрос. Отсюда кажется, что этот сайт может быть релевантным.

1 голос
/ 15 июля 2011

Сначала вы можете запросить у веб-службы общее количество контактов (например, 100 000), а затем запросить отдельные «страницы» контактов (например, 100 контактов / страница). По мере появления каждой страницы вы обновляете индикатор выполнения. Если запрос страницы не удался, просто повторите этот запрос и продолжите обработку. Это должен быть гораздо более надежный и эффективный подход, чем попытка собрать все 100 тыс. Контактов за один массовый запрос.

...