当我从 Web 服务下载数据时,我几乎总是使用服务。我将结果存储在数据库中,并使用游标加载器在我的视图中显示结果。但是在 Google 发布了网络库 Volley 之后,我变得有点迷茫了。volley 库使用异步任务而不是服务,并且不使用游标。我认为我应该避免异步任务并将我的数据存储在数据库中,以便我可以正确处理方向更改 - 而不会丢失数据并且需要再次下载数据。
所以我的问题是,我什么时候应该使用 Volley 而不是我自己的下载策略?
当我从 Web 服务下载数据时,我几乎总是使用服务。我将结果存储在数据库中,并使用游标加载器在我的视图中显示结果。但是在 Google 发布了网络库 Volley 之后,我变得有点迷茫了。volley 库使用异步任务而不是服务,并且不使用游标。我认为我应该避免异步任务并将我的数据存储在数据库中,以便我可以正确处理方向更改 - 而不会丢失数据并且需要再次下载数据。
所以我的问题是,我什么时候应该使用 Volley 而不是我自己的下载策略?
就个人而言,过去我发现使用服务实施起来很麻烦,但归根结底,它的结构很好,并且是一种良好的一致体验。但是线程性能......很难管理。
服务 查询 -> 数据库加载 -> 通知
UI 启动查询和光标加载 -> 更新 ui。
使用 volley,很容易跳过之前在服务和数据库中处理的整个组件。
UI Volley 请求 -> Volley 响应 -> 更新 ui
但是,这会很快分崩离析,具体取决于您尝试显示的数据,甚至可能是您针对以下任何要求查询的服务器
用户可能会向下滚动并拉入更多页面。但是,当用户返回活动或什至只是旋转时,对 Volley 的调用将仅返回初始页面的结果,除非您特别记住该页面包含的所有其他查询。对于一个更方便的架构来说,这变成了很多工作。甚至是稍微不同的页面,如果他们所做的只是旋转手机,这可能会给用户带来不一致的体验。
更容易在本地应用更改,然后随时应用到服务器。仅使用 volley,您必须同步进行 REST 更新和重新查询(所有先前的查询)。
排球真的很快。但是,除了可用的缓存命中之外,它缺乏任何持久性,这可能取决于您正在查询的服务器。激进的缓存甚至可以用陈旧的数据对您的应用程序造成严重破坏。在浏览多个活动时,从本地数据库中提取数据提供了一致且快速的体验,这些活动实际上可能引用了过去查询中的数据。纯粹的 volley 体验可能需要您从以前的查询中查询技术上已经拥有的数据,但没有中央数据存储可以从中获取该数据。
这些天我实际上跳过了服务部分,但其他一切都来自传统拱门
UI启动 volley 查询和光标加载 -> 更新 ui
Volley 查询-> 更新数据库 -> 通知
此外,没有什么可以阻止您让 ui ping 服务,然后该服务使用 volley... 它看起来更传统,可能会将更多的控制逻辑转移到更集中的地方,但事实上它是从内部运行的“服务”实际上并没有提供任何技术优势。
我希望这会有所帮助。基本上,不要只尝试排球,我试过了,如果这对你有用,这将是一个非常具体和简单的应用程序,希望我已经确定了主要缺陷。
此外,尽管它正在服务中,但我发现了与 robospice 相同的陷阱......但是...... YMMV
Volley 只是一个帮助层,用于与管理线程和东西的服务器进行通信。是的,它已经实现了不错的线程缓存和东西。但是你不必在你的活动中使用它。我什至会说你不应该。我们都知道服务实际上是做任何后台网络工作的地方。它旨在在配置更改后保留下来,并且是您的应用程序声明它确实在后台工作的自然方式,系统应格外小心。
想象一下,没有Volley。你会怎么办?我打赌你会在服务中实现你的线程支持,对吧(我们都知道服务在主线程上工作)?它可能像 IntentService 一样简单,它是单个静态工作线程和它的处理程序。或者你可能会喜欢并使用 ExecutorService 来拥有一个线程池。或者你可以发疯,new Thread()
每次都开始onStartCommand()
。任何适合您的需求和口味的东西。
所以我更喜欢将 Volley 视为完成这项任务的另一种方式。这次你不需要自己做任何线程工作,你只需让 Volley 为你做这件事。
所以底线是一起使用 Volley AND Service。
我遇到了同样的问题,我不喜欢本地和网络请求的分离进程。我扩展了 Volley 库以包含本地数据库请求(用于离线内容)和网络请求的过程。
基本上我有一个 CompleteRequest 将返回:
请求如下所示:
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
}
}
));
它仍处于开发的早期阶段,但我在几个应用程序中使用它并且效果很好。我写了一个带有示例的快速自述文件,并且有示例项目可以提供帮助。
总是使用 volley 来下载东西。如果您还需要将数据保存在 db 中,您仍然可以使用它。只需重新考虑您的架构。Volley 是一个网络工具,仅此而已。
哦,凌空不使用 AsyncTasks。
Volley 旨在提供一种更方便的方式来异步执行网络请求。它不需要您继承 aService
或 an AsyncTask
,并且对于任何有经验的开发人员来说,它的语法都非常简单。
如上所述,这完全是一种方便。如果你有一个运作良好的机制,那么一定要使用它。如果您发现自己不断重写代码以遵循现有模型,您可能需要查看可重用库,例如Volley
droidQuery 。
没有正确或错误的答案。但是,可能存在更好或更坏的因素。这里的主要比较是速度。Volley拥有快速的速度,并计划OKHTTP
很快提供支持,并成为Android SDK(或兼容包)的一部分,继续与 Android 平台一起发展。如果这些事情对您很重要,那么也许您应该切换到未来的应用程序(除非您在当前应用程序中有明显的滞后,否则我很难看到更改工作代码的意义)。