Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 获取大量数据,最好的方法是什么?_Android - Fatal编程技术网

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

Android 获取大量数据,最好的方法是什么?,android,Android,我有几个URLs我需要从中获取数据,这应该按顺序进行,一个接一个。请求那些URLs返回的数据量相对较大。我需要能够重新安排失败的特定下载 最好的方式是什么?我应该使用IntentService、装载机还是其他什么 附加说明:我不仅需要下载数据,还需要对数据进行后期处理(在db中创建表,用数据填充,等等)。因此,DownloadManger在这里帮不上忙。我认为方法是在数组中加载URL,然后启动一个异步任务,将布尔值返回到onPostExecute,指示操作是否成功。然后,保留一个全局int索引,

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

最好的方式是什么?我应该使用
IntentService
装载机
还是其他什么


附加说明:我不仅需要下载数据,还需要对数据进行后期处理(在db中创建表,用数据填充,等等)。因此,
DownloadManger
在这里帮不上忙。

我认为方法是在数组中加载URL,然后启动一个异步任务,将布尔值返回到onPostExecute,指示操作是否成功。然后,保留一个全局int索引,如果成功,可以使用下一个索引运行AsyncTask,否则使用相同的索引运行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));
}


}
private int index=0;
//此数组必须加载URL
私人ArrayList urlsArray;
新建MyDownloaderAsyncTask().execute(urlsArray.get(index));
类MyDownloaderAsyncTask扩展异步任务{
@凌驾
doInBackground(字符串…输入){
//downlaod my data是下载数据并返回布尔值的函数
返回downloadMyData();
}
@凌驾
onPostExecute(布尔结果){
如果(结果)
新建MyDownloaderAsyncTask().execute(urlsArray.get(++index));
其他的
新建MyDownloaderAsyncTask().execute(urlsArray.get(index));
}
}

希望此帮助

最简单的方法可能是使用系统下载管理器


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

我建议提供这方面的服务。提供服务可以解决许多问题

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

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

  • 将允许您与服务器建立独立的通信,以便在无需用户交互的情况下优先下载


我会使用
IntentService

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


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

我刚刚完成了一个开源库,它可以完全满足您的需要。使用,您可以执行以下操作:

$.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
,等等。

尝试使用
WakefulIntentService
创建使用wakelocks保持任务活动和运行的长时间运行作业


另外,如果你的整个应用程序进程都被破坏了,你可能需要考虑将任务队列持久化到磁盘,使用类似于@Murtuza Kabul的东西,我想说是使用服务,但这有点复杂。我们有一个类似的情况与不断的互联网接入和更新有关,尽管我们更加注重保持服务的运行。我会尽量突出主要功能,但不会过多的细节(代码归公司所有;)

  • android.permission.RECEIVE\u BOOT\u COMPLETED
    权限和
    BroadcastReceiver
    监听
    android.intent.action.BOOT\u COMPLETED
    以唤醒服务

  • 不要将服务链接到活动,您希望它一直运行。例如,我们调用
    context.startService(新的意图(context.getApplicationContext(),OurService.class))

  • 服务类只是一个简单的类,它注册并调用一个
    OurServiceHandler
    (在我们的例子中,我们进行重复检查,
    Handler
    管理“滴答声”)

  • 我们有一个
    OurServiceRunnable
    ,它是一个单例,由
    处理程序为每个测试检查和调用。它可以防止重复更新。它委托一名
    OurServiceWorker
    执行实际提升

  • 听起来很繁重,但您希望确保服务始终在运行,始终在滴答声(通过
    处理程序
    ),但一次只运行一个检查。如果使用标准的SqlLite DbHelper范例,您还将遇到数据库问题,因为您无法在多个线程上打开数据库,而且您肯定希望从主线程访问internet。我们的攻击是一个
    java.util.concurrent.locks.ReentrantLock
    保护对数据库的访问,但是您可能会在UI线程上保留数据库访问,并通过
    处理程序传递数据库操作


    除此之外,只需按照“获取任务、下载任务、完成任务”的方式保持下载的原子性,或使其能够从失败状态中恢复,例如下载确定、尝试完成。

    您应该查看截击库:

    还有一段关于作者的有趣视频,发生在google io 2013上:

    这主要是因为它简化了管理这些繁琐任务的过程,这些任务包括连接检查、连接中断、队列管理、重试、恢复等

    引用javacodegeeks的“使用截击的优势:

  • Volley会自动安排所有网络请求。这意味着Volley将处理应用程序从web获取响应或图像时执行的所有网络请求
  • 截击提供了透明的数据
    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();
        }
    
    }