获取大量数据,最好的方法是什么?

我有几个URL我需要从中获取数据,这应该发生的顺序,一个接一个。 请求这些URL返回的数据量比较大。 我需要能够重新安排特定的下载失败。

什么是最好的方式去? 我应该使用IntentServiceLoaders还是其他?

附加说明:我不仅需要下载,而且需要后处理数据(在db中创build表格,填充数据等)。 所以DownloadManger不能在这里帮忙。

Solutions Collecting From Web of "获取大量数据,最好的方法是什么?"

我会使用一个IntentService

它具有许多适合您需求的优点,包括能够在不运行应用程序的情况下下载数据,并支持使用setIntentRedelivery()自动重新启动服务。

您可以为特定作业设置多个标识符,您需要执行使用Intent extras,并且可以使用SharedPreferences跟踪进度 – 这样,如果以前取消了工作,也可以继续工作。

最简单的方法可能是使用系统DownloadManager http://developer.android.com/reference/android/app/DownloadManager.html

(从我的电话回答,所以请原谅缺乏格式)

我会build议这个服务。 有服务解决了许多问题

  • 它将允许与应用程序asynchronous报告进度,以便根据数据的下载状态启用或禁用应用程序中的特定GUI

  • 它将允许您继续下载,即使用户切换到其他应用程序或closures应用程序。

  • 将允许您build立与服务器的独立通信优先下载没有用户交互。

尝试一个WakefulIntentService来创build一个长时间运行的作业,使用唤醒锁来让你的任务保持运行并运行https://github.com/commonsguy/cwac-wakeful

另外,如果你的整个应用程序进程被杀死了,你可能需要考虑将任务队列保存到磁盘,使用类似Tape的Tape

我想要的方式是加载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)); } } 

希望这个帮助

我刚刚完成了一个开源的库,可以做到你所需要的。 使用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); } })); 

您可以指定其他数据types,这将返回不同的对象types,如JSONObjectStringDocument等。

类似于@Murtuza喀布尔我会说使用一个服务,但它有点复杂。 我们有类似的情况与不断的互联网访问和更新有关,尽pipe我们更关注保持服务运行。 我会尽量突出主要的function,而不会让你淹没在太多的细节中(而代码是由公司拥有的)

  1. android.permission.RECEIVE_BOOT_COMPLETED权限和一个BroadcastReceiver侦听android.intent.action.BOOT_COMPLETED来唤醒服务。

  2. 不要将服务链接到活动,您希望它始终运行。 例如我们调用context.startService(new Intent(context.getApplicationContext(), OurService.class))

  3. 服务类只是一个简单的类,它注册并调用一个OurServiceHandler (在我们的例子中,我们触发了重复的检查, Handlerpipe理'ticks')

  4. 我们有一个OurServiceRunnable ,它是一个由Handler为每个testing检查和调用的单例。 它可以防止重叠更新。 它代表一个OurServiceWorker来做实际的提升。

听起来手脚太重了,但是你要确保服务总是在运行,总是滴答(通过Handler ),但一次只能运行一次检查。 如果您使用标准的SqlLite DbHelper范例,那么您也将遇到数据库问题,因为您无法在多个线程上打开数据库,并且您肯定希望从主线程访问Internet。 我们的破解是一个保护对数据库的访问的java.util.concurrent.locks.ReentrantLock ,但是你可以在UI线程上保持数据库访问,并通过Handler传递数据库操作。

除此之外,只需按照“获取任务,下载任务,完成任务”的方式保持下载primefaces,或者使其能够从失败状态中获取,例如下载OK,尝试完成。

你应该看看凌空图书馆:

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

还有一个有趣的video作者,发生在谷歌io 2013:

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

主要是因为它简化了许多连接检查,连接中断,队列pipe理,重试,恢复等这些苛刻任务的pipe理过程。

从javacodegeeks引用“使用排球的优势:

  1. Volley自动调度所有networking请求。 这意味着,Volley将负责处理您的应用程序执行的所有networking请求,以从Web获取响应或图像。
  2. Volley提供了透明的磁盘和内存caching。
  3. Volley提供强大的取消请求API。 这意味着您可以取消单个请求,也可以设置要取消的请求的范围或范围。
  4. 排雷提供强大的定制能力。
  5. Volley提供了debugging和跟踪工具“

从dennisdrew更新:对于大文件,最好使用volley的变体,授权使用另一个http客户机实现。 此链接提供更多详细信息:

关于这个修改的抽象文章:

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

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