从Web服务下载数据时,我几乎总是使用服务。我将结果存储在数据库中,并使用游标加载器在我的视图中显示结果。但谷歌发布网络库后,我已经变得有些困惑了。排球库使用异步任务而不是服务,并且它不使用游标。我认为我应该避免异步任务并将我的数据存储在数据库中,以便我可以正确处理方向更改 - 而不会丢失数据并且需要再次下载数据。所以我的问题是,我何时应该使用Volley而不是我自己的下载策略?
答案 0 :(得分:24)
就个人而言,过去我发现使用服务实施起来很麻烦,但最终结构良好,并且是一种良好的一致体验。但线程性能......难以管理。
<强>服务强> 查询 - &gt;数据库加载 - &gt;通知
<强> UI 强> 启动查询和游标加载 - &gt;更新ui。
对于凌空,很容易跳过先前在服务和数据库中处理的整个组件。
<强> UI 强> 排球请求 - &gt;排球响应 - &gt;更新ui
但是,根据您尝试显示的数据,甚至您要查询的服务器是否满足以下任何要求,这会很快崩溃
用户可能会向下滚动并拉入更多页面。但是,当用户返回活动或甚至只是旋转时,对Volley的调用将仅返回初始页面的结果,除非您特别记住该页面包含的所有其他查询。对于一个更方便的架构来说,这会成为很多工作。或者甚至是略有不同的页面,如果他们所做的只是旋转手机,这对用户来说可能是不一致的体验。
更容易在本地应用更改,然后随时应用于服务器。仅使用凌空,您必须同步执行REST更新和重新查询(以前的所有查询)。
这些天我实际上跳过了服务部分,但其他一切都来自传统的拱门
用户界面发起排球查询和游标加载 - &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:
请求如下:
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
}
}
));
它仍然处于开发的早期阶段,但我在几个应用程序中使用它并且它运行良好。我用一些例子写了一篇快速的自述文件,有一些示例项目可以提供帮助。
查看答案 3 :(得分:0)
总是使用排球来下载东西。如果你还需要在db中保存数据,你仍然可以使用它。只需重新思考您的架构。 Volley是一个网络工具,仅此而已。
哦,凌空不使用AsyncTasks。
答案 4 :(得分:0)
Volley旨在提供一种更方便的方式来异步执行网络请求。它不要求您为Service
或AsyncTask
创建子类,并且对于任何有经验的开发人员来说,它的语法都非常简单。
如上所述,这完全是便利。如果你有一个运作良好的机制,那么一定要使用它。如果您发现自己不断重写与现有模型相关的代码,则可能需要查看可重用的库,例如Volley
或droidQuery。
没有正确或错误的答案。但是,可能存在更好或更差的因素。这里的主要比较是速度。 Volley 拥有快速的速度,并计划尽快支持OKHTTP
,并成为 Android SDK (或兼容包)的一部分,继续增长使用Android平台。如果这些对您来说很重要,那么也许您应该为将来的应用程序切换(除非您在当前应用程序中有明显的延迟,我很难看到更改工作代码的重点)。