Robospice-addListenerIfPending-如何知道是否找到请求? [英] Robospice - addListenerIfPending - how do I know if request WAS found?
问题描述
我正在尝试使用robospice实现一个非常简单的案例:一个登录屏幕.单击登录按钮后,将显示加载动画并使用SpiceManager.execute(..)
发出请求(当然,不进行缓存.由于这是一个登录请求,因此每次都需要对服务器进行实际调用).
I am trying to implement a very simple case using robospice: a login screen. When login button is clicked, loading animation is shown and request is made using SpiceManager.execute(..)
(without caching, of course. Since it's a login request, I need to do actual call to the server every time).
因此,要处理屏幕旋转等问题,在Activity.onStart()
中,我应该使用SpiceManager.addListenerIfPending(..)
,如果请求实际上是未决的,我应该显示加载动画而不进行任何实际的请求.
So, to handle screen rotations, etc., in Activity.onStart()
I should use SpiceManager.addListenerIfPending(..)
, and if request is actually pending, I should show loading animation without doing any real request.
问题是:PendingRequestListener
没有onRequestExists()
方法.它只有onRequestNotFound()
.
The problem is: PendingRequestListener
does not have onRequestExists()
method. It only has onRequestNotFound()
.
一种可能(但不令人满意)的解决方案是始终绘制加载屏幕,然后调用addListenerIfPending(..)
,然后在onRequestNotFound()
中删除加载动画.如果没有真正的请求,这将创建闪烁"的加载屏幕,这看起来真的很糟糕.实现所需行为的正确方法是什么?
One possible (but unsatisfactory) solution, is to draw loading screen always, then call addListenerIfPending(..)
, and then remove loading animation in onRequestNotFound()
. This creates "flickering" loading screen if there was no real request, which looks really bad. What is the proper way of implementing desired behavior?
推荐答案
好吧,以防google领导这里的任何人. 正确的解决方案: 实际上,该功能已在库中.当等待请求被发现时,有一种方法会被调用,它只会执行任何操作.
Ok, in case google leads anyone here. Proper solution: in reality, this functionality is already in the library. There is a method which gets called when pending request WAS found, it just does... nothing.
您需要:
-
创建扩展
PendingRequestListener
的自己的界面:
public interface MyPendingRequestListener<T> extends PendingRequestListener<T> {
void onRequestAggregated();
}
注意:通过Robospice进行请求时,您将需要使用实现此接口的请求侦听器.
Note: you will need to use request listeneres implementing this interface when doing requests through Robospice.
创建实现RequestListenerNotifier
的自己的类.我通过复制粘贴DefaultRequestListenerNotifier
(由于方法post(..)
是私有的,所以无法扩展它)来完成此操作,因为它包含针对其他情况的porper通知实现.例如,MyRequestListenerNotifier
.
Create your own class implementing RequestListenerNotifier
. I did this by copy-pasting DefaultRequestListenerNotifier
(I was not able to extend it because method post(..)
is private) because it contains porper notification implementation for other cases. For example, MyRequestListenerNotifier
.
覆盖方法notifyListenersOfRequestAggregated
:
@Override
public <T> void notifyListenersOfRequestAggregated(final CachedSpiceRequest<T> request, Set<RequestListener<?>> listeners) {
post(new AggregatedRunnable(listeners), request.getRequestCacheKey());
}
private static class AggregatedRunnable implements Runnable {
private final Set<RequestListener<?>> listeners;
public AggregatedRunnable(final Set<RequestListener<?>> listeners) {
this.listeners = listeners;
}
@Override
public void run() {
if (listeners == null) {
return;
}
Ln.v("Notifying " + listeners.size() + " listeners of request aggregated");
synchronized (listeners) {
for (final RequestListener<?> listener : listeners) {
if (listener != null && listener instanceof MyPendingRequestListener) {
Ln.v("Notifying %s", listener.getClass().getSimpleName());
((MyPendingRequestListener<?>) listener).onRequestAggregated();
}
}
}
}
}
扩展SpiceService并覆盖以下方法(您将需要使用此自定义服务而不是标准的robospice服务):
Extend SpiceService and override the following method (you will need to use this customized service instead of standard robospice service):
protected RequestListenerNotifier createRequestRequestListenerNotifier() {
return new MyRequestListenerNotifier();
}
就是这样.现在,当您使用addListenerIfPending
时,如果找到待处理的请求,就会调用onRequestAggregated()
.
That's it. Now, when you use addListenerIfPending
, onRequestAggregated()
will be called when pending request IS found.
重要说明::仅当您在执行请求时使用Cache键时,此选项才有效.例如,您可以使用空字符串(但不 null)作为缓存键.
IMPORTANT NOTE: This will only work when you use Cache key when doing request. For example, you can use empty string (but NOT null) as cache key.
示例:
//doing request for the first time
spiceManager.execute(request, "", DurationInMillis.ALWAYS_EXPIRED, requestListener);
//...
//checking if request is pending e.g. when activity is restarted
spiceManager.addListenerIfPending(responseClass, "", requestListener);
这篇关于Robospice-addListenerIfPending-如何知道是否找到请求?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!