2013-06-29 2 views
22

У меня есть число URL s Мне нужно получить данные, это должно происходить по порядку, по одному. Количество данных, возвращенных путем запроса этих URL s, относительно велико. Мне нужно иметь возможность перенести определенные загрузки, которые не удались.Извлечение большого количества данных, что является лучшим способом?

Каков наилучший способ? Должен ли я использовать IntentService, Loaders или что-то еще?

Дополнительное примечание: Мне нужно будет не только загружать, но и обрабатывать данные (создавать таблицы в db, заполнять их данными и т. Д.). Так что DownloadManger здесь не может быть полезен.

+3

Возможно 'IntentService' если вы хотите сохранить загрузку, пока приложение закрыто. – Ran

+0

Просто идея: возможно, используя couchDB как услугу? http://arandomurl.com/2011/02/13/developing-with-couchdb-on-android.html –

ответ

12

Я бы использовал IntentService.

Он имеет ряд преимуществ, которые подходят для ваших нужд, в том числе возможность загрузки данных без запуска вашего приложения и поддержки автоматического перезапуска службы с использованием setIntentRedelivery().

Вы можете установить количество идентификаторов для конкретного задания, которые необходимо выполнить с помощью Intent статистов, и вы можете следить за прогрессом, используя SharedPreferences - таким образом вы можете также возобновить работу, если она была ранее отменена.

2

Я думаю, что путь к загрузке - это загрузка URL-адресов в массив, а затем запуск AsyncTask, возвращающий логическое значение в onPostExecute, указывающее, имеет ли операция успех или нет. то, сохраняя глобальный индекс int, вы можете запустить AsyncTask со следующим индексом, если успех или тот же индекс в противном случае. Вот псевдокод

private int index=0; 
//this array must be loaded with urls 
private ArrayList<String> urlsArray; 

new MyDownloaderAsyncTask().execute(urlsArray.get(index)); 


class MyDownloaderAsyncTask extends AsyncTask<String,String,Boolean>{ 

@Override 
doInBackground(String... input){ 

//downlaod my data is the function which download data and return a boolean 
return downloadMyData(); 

} 

@Override 
onPostExecute(Boolean result){ 

if(result) 
    new MyDownloaderAsyncTask().execute(urlsArray.get(++index)); 
else 
    new MyDownloaderAsyncTask().execute(urlsArray.get(index)); 
} 


} 

надеюсь, что это поможет

+0

Объем данных относительно велик, AsyncTask не подходит для таких задач. – Eugene

5

Самый простой способ, вероятно, использовать систему DownloadManager http://developer.android.com/reference/android/app/DownloadManager.html

(ответ с телефона, поэтому, пожалуйста, простите за отсутствие форматирования)

+0

Мне нужно выполнить некоторую постобработку с извлеченными данными, поэтому DownloadManager не является выбором, я добавил вопрос с этой информацией. – Eugene

+2

Не могли бы вы просто выполнить постобработку после завершения загрузки? Вы знаете, что вам не нужно выставлять загруженный файл вашему пользователю, или вам нужно делать свою обработку потоковым способом во время загрузки? – dnaq

5

Я бы предложил услугу для этого. Имея сервис решает много проблем

  • Это позволило бы сообщать о прогрессе в асинхронном режиме приложения, так что вы можете включить или отключить конкретный графический интерфейс в приложении на основе состояния загрузки данных

  • Это позволит вам продолжить загрузку, даже если пользователь переключится на другое приложение или закрывает приложение.

  • Позволяет устанавливать независимую связь с сервером, чтобы устанавливать приоритеты при загрузке без участия пользователя.

1

Я только что закончил библиотеку с открытым исходным кодом, которая может делать именно то, что вам нужно. Используя droidQuery, вы можете сделать что-то вроде этого:

$.ajax(new AjaxOptions().url("http://www.example.com") 
         .type("GET") 
         .dataType("JSON") 
         .context(this) 
         .success(new Function() { 
          @Override 
          public void invoke($ droidQuery, Object... params) { 
           //since dataType is JSON, params[0] is a JSONObject 
           JSONObject obj = (JSONObject) params[0]; 
           //TODO handle data 
           //TODO start the next ajax task 
          } 
         }) 
         .error(new Function() { 
          @Override 
          public void invoke($ droidQuery, Object... params) { 
           AjaxError error = params[0]; 
           //TODO adjust error.options before retry: 
           $.ajax(error.request, error.options); 
          } 
         })); 

Вы можете указать другие типы данных, которые будут возвращать различные типы объектов, такие как JSONObject, String, Document и т.д.

3

Пробуйте WakefulIntentService для создания долговременной работы, использующей wakelocks, чтобы ваша задача была жива и запущена. https://github.com/commonsguy/cwac-wakeful.

Кроме того, если ваш весь процесс приложения убитого, вы можете захотеть взглянуть на сохраняющиеся очереди задач на диск, используя что-то вроде Tape, from Square

1

похожего на @Murtuza Кабул я бы сказал, использовать услугу, но это немного сложно. У нас есть аналогичная ситуация, связанная с постоянным доступом в Интернет и обновлениями, хотя наша компания уделяет больше внимания поддержанию работы службы. Постараюсь выделить основные черты, не тонет вас слишком много деталей (и кода принадлежат компании;))

  1. android.permission.RECEIVE_BOOT_COMPLETED разрешения и BroadcastReceiver прослушивание android.intent.action.BOOT_COMPLETED совать службу просыпается.

  2. Не связывайте службу с Activity, вы хотите, чтобы она работала все время. например, мы называем context.startService(new Intent(context.getApplicationContext(), OurService.class))

  3. классом обслуживания является лишь простым классом, который регистрирует и называет OurServiceHandler (как в нашем случае мы выпалить повторные проверки и Handler управляет «галочками»)

  4. У нас есть OurServiceRunnable, который является одноточечным, который проверяется и вызывается Handler для каждого теста. Он защищает от перекрывающихся обновлений. Он делегирует OurServiceWorker для фактического подъема.

Звуки тяжелой рукой, но вы хотите, чтобы убедиться, что служба всегда работает, всегда тикают (через Handler), но только работает один чек в то время. Вы также столкнетесь с проблемой базы данных, если используете стандартную парадигму SqlLite DbHelper, так как вы не можете открыть БД на нескольких потоках, а вы определенно хотите получить доступ в Интернет с основного потока. Наш хак был java.util.concurrent.locks.ReentrantLock, защищающий доступ к БД, но вы, вероятно, могли бы поддерживать доступ к БД в потоке пользовательского интерфейса и выполнять операции БД через Handler.

Помимо этого, это просто вопрос сохранения атомных данных с точки зрения «получить задание, загрузить задачу, выполнить задачу» или включить ее для сбоя из отказавшего состояния, например, загрузить ОК, попытаться завершить.

0

Вы должны взглянуть на библиотеку залпового:

http://www.javacodegeeks.com/2013/06/android-volley-library-example.html

Существует также интересное видео автора, который состоялся в Google IO 2013:

http://www.youtube.com/watch?v=yhv8l9F44qo

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

Цитирование из javacodegeeks «Преимущества использования Volley:

  1. Volley автоматически планировать все сетевые запросы.Это означает, что Volley будет следить за всеми сетевыми запросами, которые приложение выполняет для получения ответа или изображения из Интернета.
  2. Волейл обеспечивает прозрачный диск и кеширование памяти.
  3. Volley предоставляет мощный API запроса отмены. Это означает, что вы можете отменить один запрос, или вы можете установить блоки или области запросов для отмены.
  4. Volley обеспечивает мощные возможности настройки.
  5. Volley обеспечивает отладки и трассировки инструменты»

Обновление от dennisdrew:. Для больших файлов, лучше использовать вариант залпа, который авторизироваться с помощью другой реализации клиента HTTP Эта ссылка дает более подробную информацию:

The залп статья об этой модификации:

http://ogrelab.ikratko.com/android-volley-examples-samples-and-demos/

GitHub файл деталь:

https://github.com/ogrebgr/android_volley_examples/blob/master/src/com/github/volley_examples/toolbox/ExtHttpClientStack.java

+0

В видео IO автор сказал, что Volley ужасен для больших загрузок. – dennisdrew

+0

Кто-то обратился к этой проблеме здесь: http://ogrelab.ikratko.com/using-volley-android-with-external-httpclient-4-2-x/ – Gomoku7

+0

Простите мое n00bness. Как это относится к предполагаемой ужасности Волей с большими передачами данных? – dennisdrew

0
public class FetchDataFromDBThread implements Runnable { 

    /* 
    * Defines the code to run for this task. 
    */ 
    @Override 
    public void run() { 
     // Moves the current Thread into the background 
     android.os.Process 
       .setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND); 

     FetchDataFromDB(); 
    } 

}