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

时间:2013-06-29 08:24:39

标签: android

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

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

附加说明:我不仅需要下载,还需要后处理数据(在db中创建表,用数据填充它等)。所以DownloadManger在这里无济于事。

9 个答案:

答案 0 :(得分:12)

我会使用IntentService

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

您可以为特定作业设置多个标识符,需要使用Intent个附加功能执行,并且可以使用SharedPreferences跟踪进度 - 这样您也可以恢复工作如果以前被取消了。

答案 1 :(得分:5)

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

(从我的手机接听,请原谅缺乏格式化)

答案 2 :(得分:5)

我建议为此服务。服务可以解决许多问题

  • 它允许异步报告进度,因此您可以根据数据的下载状态启用或禁用应用程序中的特定gui

  • 即使用户切换到其他应用程序或关闭应用程序,也可以继续下载。

  • 允许您与服务器建立独立的通信,以便在没有用户交互的情况下确定下载的优先级。

答案 3 :(得分:3)

尝试使用WakefulIntentService创建一个长期运行的作业,该作业使用唤醒锁来保持您的任务生效并运行https://github.com/commonsguy/cwac-wakeful

此外,如果您的整个应用程序进程被终止,您可能希望使用类似Tape, from Square

之类的内容来查看将任务队列保存到磁盘

答案 4 :(得分:2)

我认为要采用的方法是在数组中加载url,然后启动AsyncTask,将boolean返回给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));
}


}

希望这个帮助

答案 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);
                            }
                        }));

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

答案 6 :(得分: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管理'ticks')

  4. 我们有一个OurServiceRunnable,它是一个单例,每个测试由Handler检查和调用。它可以防止重叠更新。它委托OurServiceWorker进行实际解除。

  5. 声音很重,但你想确保服务始终在运行,总是勾选(通过Handler),但一次只运行一次检查。如果您使用标准的SqlLite DbHelper范例,您也将遇到数据库问题,因为您无法在多个线程上打开数据库,并且肯定希望从主线程访问Internet。我们的hack是java.util.concurrent.locks.ReentrantLock保护访问数据库的权限,但您可以在UI线程上保持数据库访问权限并通过Handler传递数据库操作。

    除此之外,只需按照“获取任务,下载任务,完成任务”或使其从失败状态中获取,例如已下载确定,尝试完成,就可以保持下载的原子性。

答案 7 :(得分: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. Volley提供透明的磁盘和内存缓存。
  3. Volley提供强大的取消请求API。这意味着您可以取消单个请求,也可以设置要取消的请求块或范围。
  4. Volley提供强大的自定义功能。
  5. Volley提供调试和跟踪工具“
  6. 来自dennisdrew的更新: 对于大文件,最好使用一个使用另一个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

答案 8 :(得分: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();
    }

}