12

当我从 Web 服务下载数据时,我几乎总是使用服务。我将结果存储在数据库中,并使用游标加载器在我的视图中显示结果。但是在 Google 发布了网络库 Volley 之后,我变得有点迷茫了。volley 库使用异步任务而不是服务,并且不使用游标。我认为我应该避免异步任务并将我的数据存储在数据库中,以便我可以正确处理方向更改 - 而不会丢失数据并且需要再次下载数据。

所以我的问题是,我什么时候应该使用 Volley 而不是我自己的下载策略?

4

5 回答 5

24

传统拱门

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

服务 查询 -> 数据库加载 -> 通知

UI 启动查询和光标加载 -> 更新 ui。

仅排球

使用 volley,很容易跳过之前在服务和数据库中处理的整个组件。

UI Volley 请求 -> Volley 响应 -> 更新 ui

但是,这会很快分崩离析,具体取决于您尝试显示的数据,甚至可能是您针对以下任何要求查询的服务器

  • 所显示的数据未由相同的 URL 完全描述(例如页面)

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

  • 必须修改数据

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

  • 速度和持久性

排球真的很快。但是,除了可用的缓存命中之外,它缺乏任何持久性,这可能取决于您正在查询的服务器。激进的缓存甚至可以用陈旧的数据对您的应用程序造成严重破坏。在浏览多个活动时,从本地数据库中提取数据提供了一致且快速的体验,这些活动实际上可能引用了过去查询中的数据。纯粹的 volley 体验可能需要您从以前的查询中查询技术上已经拥有的数据,但没有中央数据存储可以从中获取该数据。

混合排球和光标

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

UI启动 volley 查询和光标加载 -> 更新 ui

Volley 查询-> 更新数据库 -> 通知

此外,没有什么可以阻止您让 ui ping 服务,然后该服务使用 volley... 它看起来更传统,可能会将更多的控制逻辑转移到更集中的地方,但事实上它是从内部运行的“服务”实际上并没有提供任何技术优势。

概括

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

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

于 2013-08-21T22:02:52.693 回答
11

Volley 只是一个帮助层,用于与管理线程和东西的服务器进行通信。是的,它已经实现了不错的线程缓存和东西。但是你不必在你的活动中使用它。我什至会说你不应该。我们都知道服务实际上是做任何后台网络工作的地方。它旨在在配置更改后保留下来,并且是您的应用程序声明它确实在后台工作的自然方式,系统应格外小心。

想象一下,没有Volley。你会怎么办?我打赌你会在服务中实现你的线程支持,对吧(我们都知道服务在主线程上工作)?它可能像 IntentService 一样简单,它是单个静态工作线程和它的处理程序。或者你可能会喜欢并使用 ExecutorService 来拥有一个线程池。或者你可以发疯,new Thread()每次都开始onStartCommand()。任何适合您的需求和口味的东西。

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

所以底线是一起使用 Volley AND Service。

于 2013-08-20T12:46:08.950 回答
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上查看

于 2013-09-17T19:26:22.927 回答
0

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

哦,凌空不使用 AsyncTasks。

于 2013-08-04T18:21:58.967 回答
0

Volley 旨在提供一种更方便的方式来异步执行网络请求。它不需要您继承 aService或 an AsyncTask,并且对于任何有经验的开发人员来说,它的语法都非常简单。

如上所述,这完全是一种方便。如果你有一个运作良好的机制,那么一定要使用它。如果您发现自己不断重写代码以遵循现有模型,您可能需要查看可重用库,例如Volley​​ droidQuery 。

没有正确或错误的答案。但是,可能存在更好或更坏的因素。这里的主要比较是速度。Volley拥有快速的速度,并计划OKHTTP很快提供支持,并成为Android SDK(或兼容包)的一部分,继续与 Android 平台一起发展。如果这些事情对您很重要,那么也许您应该切换到未来的应用程序(除非您在当前应用程序中有明显的滞后,否则我很难看到更改工作代码的意义)。

于 2013-08-21T21:16:26.070 回答