使用游标加载器进行排球或服务

时间:2013-08-04 14:14:20

标签: android service cursor android-volley

从Web服务下载数据时,我几乎总是使用服务。我将结果存储在数据库中,并使用游标加载器在我的视图中显示结果。但谷歌发布网络库后,我已经变得有些困惑了。排球库使用异步任务而不是服务,并且它不使用游标。我认为我应该避免异步任务并将我的数据存储在数据库中,以便我可以正确处理方向更改 - 而不会丢失数据并且需要再次下载数据。所以我的问题是,我何时应该使用Volley而不是我自己的下载策略?

5 个答案:

答案 0 :(得分:24)

传统拱门

就个人而言,过去我发现使用服务实施起来很麻烦,但最终结构良好,并且是一种良好的一致体验。但线程性能......难以管理。

<强>服务 查询 - &gt;数据库加载 - &gt;通知

<强> UI 启动查询和游标加载 - &gt;更新ui。

仅排球

对于凌空,很容易跳过先前在服务和数据库中处理的整个组件。

<强> UI 排球请求 - &gt;排球响应 - &gt;更新ui

但是,根据您尝试显示的数据,甚至您要查询的服务器是否满足以下任何要求,这会很快崩溃

  • 所显示的数据未通过相同的URL(例如,页面)完整描述

用户可能会向下滚动并拉入更多页面。但是,当用户返回活动或甚至只是旋转时,对Volley的调用将仅返回初始页面的结果,除非您特别记住该页面包含的所有其他查询。对于一个更方便的架构来说,这会成为很多工作。或者甚至是略有不同的页面,如果他们所做的只是旋转手机,这对用户来说可能是不一致的体验。

  • 必须修改数据

更容易在本地应用更改,然后随时应用于服务器。仅使用凌空,您必须同步执行REST更新和重新查询(以前的所有查询)。

  • 速度和持久性
排球很快。但是,除了可用的缓存命中之外,它缺少任何持久性,这可能取决于您要查询的服务器。积极的缓存甚至会对您的应用程序造成严重破坏。在浏览可能实际引用过去查询中的数据的多个活动时,从本地数据库中提取可提供一致且快速的体验。纯粹的排球体验可能要求您从先前的查询中查询技术上已有的数据,但没有中央数据存储来从中获取数据。

Hybrid Volley and Cursors

这些天我实际上跳过了服务部分,但其他一切都来自传统的拱门

用户界面发起排球查询和游标加载 - &gt;更新ui

排球查询 - &gt;更新数据库 - &gt;通知

此外,没有什么可以阻止你使用ui ping服务然后服务使用凌空......看起来更传统可能有价值将更多的控制逻辑移动到更集中的地方,但事实是它运行从“服务”中实际上没有任何技术优势。

摘要

我希望有所帮助。基本上,不要试图只是排球,我试过,如果这对你有用,我希望我已经找到了主要的陷阱,这将是一个非常具体和简单的应用程序。

此外,我发现尽管它正在服务中,但是我发现了与robospice相同的陷阱......但是... YMMV

答案 1 :(得分:11)

Volley只是一个辅助层,用于与管理线程和内容的服务器进行通信。是的,它已经实现了很好的线程缓存和东西。但您不必在活动中使用它。我甚至会说你不应该。我们都知道服务实际上是进行任何后台网络工作的地方。它旨在经受配置更改,是您的应用程序声明它在后台工作的自然方式,系统应特别小心。

想象一下,没有排球。你会怎么做?我打赌你会在服务中使用线程支持,这对(我们都知道服务在主线程上运行)?它可能像IntentService一样简单,它是一个静态工作线程和一个处理程序。或者您可能会喜欢并使用ExecutorService来拥有一个线程池。或者你可以发疯,每次new Thread()开始onStartCommand()。无论什么适合您的需求和品味。

所以我更喜欢将Volley视为完成这项任务的另一种方式。这次你不需要自己做任何线程的工作,你只需让Volley为你做。

所以底线是同时使用Volley AND Service。

答案 2 :(得分:1)

我遇到了同样的问题,我不喜欢为本地和网络请求分离进程。 我扩展了Volley库,包括了一个本地数据库请求(用于离线内容)和网络请求的过程。

基本上我有一个将返回的CompleteRequest:

  • 一个中间响应,可以来自http缓存或来自本地数据库(并行运行,最快完成返回结果,第二个被忽略)
  • 最终回复,来自网络(或错误)

请求如下:

public class SampleRequest extends CompleteRequest<Object> {

    public SampleRequest(int method, String url, ResponseListener<Object> responseListener, Response.ErrorListener errorListener) {
        super(method, url, responseListener, errorListener);
    }

    @Override
    protected Object getLocalResponse() {
        // query your local database for example
        // return the result or null if there is no result from database
        return new Object();
    }

    @Override
    public void saveNetworkResponseToLocal(Object response) {
        // save the network response to the local database
        // next time the request is performed the local response will return the result faster than the network request
    }

    @Override
    protected BallResponse<Object> parseBallNetworkResponse(NetworkResponse response) {
        // parse the result from the network request, in the same way than with volley
        return Response.success(new Object());
    }
}

你执行这样的请求,响应监听器包含中间响应和最终响应:

mRequestQue.add(new SampleRequest(Request.Method.GET, "http://some.url", new ResponseListener<Object>() {
    @Override
    public void onIntermediateResponse(Object response, BallResponse.ResponseSource responseSource) {
        // intermediate response, such as from local database or soft cached network response
    }

    @Override
    public void onFinalResponse(Object response, BallResponse.ResponseSource responseSource) {
        // final response, which is the network response
    }

    @Override
    public void onFinalResponseIdenticalToIntermediate(BallResponse.ResponseSource responseSource) {
        // final response is identical to intermediate one
        // happens when intermediate is from soft cache and network response is identical (not modified)
    }

}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        // network response is an error, in the same way than with volley
    }
}
));

它仍然处于开发的早期阶段,但我在几个应用程序中使用它并且它运行良好。我用一些例子写了一篇快速的自述文件,有一些示例项目可以提供帮助。

您可以在https://github.com/lukaspili/Volley-Ball

查看

答案 3 :(得分:0)

总是使用排球来下载东西。如果你还需要在db中保存数据,你仍然可以使用它。只需重新思考您的架构。 Volley是一个网络工具,仅此而已。

哦,凌空不使用AsyncTasks。

答案 4 :(得分:0)

Volley旨在提供一种更方便的方式来异步执行网络请求。它不要求您为ServiceAsyncTask创建子类,并且对于任何有经验的开发人员来说,它的语法都非常简单。

如上所述,这完全是便利。如果你有一个运作良好的机制,那么一定要使用它。如果您发现自己不断重写与现有模型相关的代码,则可能需要查看可重用的库,例如VolleydroidQuery

没有正确或错误的答案。但是,可能存在更好或更差的因素。这里的主要比较是速度。 Volley 拥有快速的速度,并计划尽快支持OKHTTP,并成为 Android SDK (或兼容包)的一部分,继续增长使用Android平台。如果这些对您来说很重要,那么也许您应该为将来的应用程序切换(除非您在当前应用程序中有明显的延迟,我很难看到更改工作代码的重点)。