robospice
robospice copied to clipboard
Loading from cache does not work after fragment is resumed
As long as I am staying in the same fragment the cache works perfectly fine. BUT as soon as I am switching the app to the background and then reloading the data onResume(), the cache is not valid anymore and a network connection is made.
Here is my code (in fragment.onResume()):
protected void loadData(final OnDataLoadListener onDataLoadListener) {
final ReverseStringRequestListener listener = new ReverseStringRequestListener(onDataLoadListener);
final String cacheKey = "cacheKey234234";
final ConfigFeedRequest request = new ConfigFeedRequest("http://app.tty-eli.com/index.php?id=3");
getSpiceManager().getFromCacheAndLoadFromNetworkIfExpired(request, cacheKey, DurationInMillis.ONE_SECOND * 50, listener);
}
Any ideas why this might happen? I am creating the SpiceManager in the class header of the fragment like that:
private SpiceManager spiceManager = new SpiceManager(InMemorySpiceService.class);
Here is the log:
10-07 16:07:06.595 5618-5618/at.tty_eli.app D//SpiceManager.java:212﹕ 16:07:06.606 main SpiceManager started.
10-07 16:07:06.605 5618-5618/at.tty_eli.app V/AppointmentFragment_﹕ onResume
10-07 16:07:06.605 5618-5618/at.tty_eli.app D//SpiceManager.java:489﹕ 16:07:06.619 main adding request to request queue
10-07 16:07:06.605 5618-5618/at.tty_eli.app D/AbsListView﹕ onVisibilityChanged() is called, visibility : 0
10-07 16:07:06.605 5618-5618/at.tty_eli.app D/AbsListView﹕ unregisterIRListener() is called
10-07 16:07:06.615 5618-6034/at.tty_eli.app V//SpiceManager.java:1191﹕ 16:07:06.623 SpiceManagerThread 2 Binding to service.
10-07 16:07:06.625 5618-5618/at.tty_eli.app D//SpiceService.java:134﹕ 16:07:06.631 main SpiceService instance created.
10-07 16:07:06.625 5618-5618/at.tty_eli.app D/AbsListView﹕ unregisterIRListener() is called
10-07 16:07:06.625 5618-6034/at.tty_eli.app V//SpiceManager.java:1197﹕ 16:07:06.633 SpiceManagerThread 2 Binding to service succeeded.
10-07 16:07:06.625 5618-6034/at.tty_eli.app D//SpiceManager.java:1245﹕ 16:07:06.637 SpiceManagerThread 2 Waiting for service to be bound.
10-07 16:07:06.645 5618-5618/at.tty_eli.app V//SpiceService.java:506﹕ 16:07:06.656 main Pending requests : 0
10-07 16:07:06.645 5618-5618/at.tty_eli.app V//SpiceService.java:508﹕ 16:07:06.658 main Stop foreground
10-07 16:07:06.655 5618-5618/at.tty_eli.app D//SpiceServiceListenerNotifier.java:33﹕ 16:07:06.662 main Message Queue starting
10-07 16:07:06.655 5618-5618/at.tty_eli.app D//SpiceManager.java:1088﹕ 16:07:06.664 main Bound to service : InMemorySpiceService
10-07 16:07:06.665 5618-6034/at.tty_eli.app D//SpiceManager.java:1252﹕ 16:07:06.673 SpiceManagerThread 2 Bound ok.
10-07 16:07:06.665 5618-6034/at.tty_eli.app D//SpiceManager.java:286﹕ 16:07:06.678 SpiceManagerThread 2 Sending request to service : CachedSpiceRequest
10-07 16:07:06.675 5618-6034/at.tty_eli.app D//RequestProcessor.java:63﹕ 16:07:06.683 SpiceManagerThread 2 Adding request to queue 1121951496: CachedSpiceRequest [requestCacheKey=cacheKey234234, cacheDuration=50000, spiceRequest=at.tty_eli.app.network.ConfigFeedRequest@42c24c50] size is 0
10-07 16:07:06.675 5618-6034/at.tty_eli.app D//RequestProcessor.java:85﹕ 16:07:06.689 SpiceManagerThread 2 Adding entry for type class at.tty_eli.app.network.ConfigFeedResponse and cacheKey cacheKey234234.
10-07 16:07:06.685 5618-6034/at.tty_eli.app D//RequestProgressManager.java:61﹕ 16:07:06.692 SpiceManagerThread 2 Request was added to queue.
10-07 16:07:06.685 5618-6034/at.tty_eli.app D//SpiceServiceListenerNotifier.java:146﹕ 16:07:06.695 SpiceManagerThread 2 Message queue is Handler (android.os.Handler) {42dfa580}
10-07 16:07:06.685 5618-5618/at.tty_eli.app D//SpiceServiceListenerNotifier.java:175﹕ 16:07:06.698 main Processing request added: CachedSpiceRequest [requestCacheKey=cacheKey234234, cacheDuration=50000, spiceRequest=at.tty_eli.app.network.ConfigFeedRequest@42c24c50]
10-07 16:07:06.695 5618-6034/at.tty_eli.app D//RequestProgressManager.java:82﹕ 16:07:06.703 SpiceManagerThread 2 Sending progress PENDING
10-07 16:07:06.695 5618-6034/at.tty_eli.app D//SpiceServiceListenerNotifier.java:146﹕ 16:07:06.708 SpiceManagerThread 2 Message queue is Handler (android.os.Handler) {42dfa580}
10-07 16:07:06.705 5618-5618/at.tty_eli.app V//DefaultRequestListenerNotifier.java:131﹕ 16:07:06.710 main Notifying 1 listeners of progress com.octo.android.robospice.request.listener.RequestProgress@42c24c88
10-07 16:07:06.705 5618-6038/at.tty_eli.app D//DefaultRequestRunner.java:83﹕ 16:07:06.714 Thread-6031 Processing request : CachedSpiceRequest [requestCacheKey=cacheKey234234, cacheDuration=50000, spiceRequest=at.tty_eli.app.network.ConfigFeedRequest@42c24c50]
10-07 16:07:06.705 5618-6034/at.tty_eli.app V//SpiceService.java:506﹕ 16:07:06.713 SpiceManagerThread 2 Pending requests : 1
10-07 16:07:06.705 5618-6038/at.tty_eli.app D//DefaultRequestRunner.java:97﹕ 16:07:06.718 Thread-6031 Loading request from cache : CachedSpiceRequest [requestCacheKey=cacheKey234234, cacheDuration=50000, spiceRequest=at.tty_eli.app.network.ConfigFeedRequest@42c24c50]
10-07 16:07:06.715 5618-6038/at.tty_eli.app D//RequestProgressManager.java:82﹕ 16:07:06.720 Thread-6031 Sending progress READING_FROM_CACHE
10-07 16:07:06.715 5618-6038/at.tty_eli.app D//SpiceServiceListenerNotifier.java:146﹕ 16:07:06.727 Thread-6031 Message queue is Handler (android.os.Handler) {42dfa580}
10-07 16:07:06.715 5618-5618/at.tty_eli.app V//DefaultRequestListenerNotifier.java:131﹕ 16:07:06.729 main Notifying 1 listeners of progress com.octo.android.robospice.request.listener.RequestProgress@42b0d130
10-07 16:07:06.725 5618-6034/at.tty_eli.app V//SpiceService.java:508﹕ 16:07:06.716 SpiceManagerThread 2 Stop foreground
10-07 16:07:06.725 5618-6038/at.tty_eli.app D//LruCacheObjectPersister.java:47﹕ 16:07:06.732 Thread-6031 Miss from lru cache for cacheKey234234
10-07 16:07:06.725 5618-6038/at.tty_eli.app D//LruCacheObjectPersister.java:47﹕ 16:07:06.737 Thread-6031 Miss from lru cache for cacheKey234234
10-07 16:07:06.735 5618-6038/at.tty_eli.app D//DefaultRequestRunner.java:129﹕ 16:07:06.741 Thread-6031 Cache content not available or expired or disabled
10-07 16:07:06.745 5618-6038/at.tty_eli.app D//DefaultRequestRunner.java:148﹕ 16:07:06.751 Thread-6031 Calling netwok request.
10-07 16:07:06.745 5618-6038/at.tty_eli.app D//RequestProgressManager.java:82﹕ 16:07:06.755 Thread-6031 Sending progress LOADING_FROM_NETWORK
10-07 16:07:06.755 5618-6038/at.tty_eli.app D//SpiceServiceListenerNotifier.java:146﹕ 16:07:06.760 Thread-6031 Message queue is Handler (android.os.Handler) {42dfa580}
10-07 16:07:06.755 5618-5618/at.tty_eli.app V//DefaultRequestListenerNotifier.java:131﹕ 16:07:06.763 main Notifying 1 listeners of progress com.octo.android.robospice.request.listener.RequestProgress@42c11c38
10-07 16:07:10.435 5618-6038/at.tty_eli.app D//DefaultRequestRunner.java:151﹕ 16:07:10.442 Thread-6031 Network request call ended.
10-07 16:07:10.435 5618-6038/at.tty_eli.app D//DefaultRequestRunner.java:171﹕ 16:07:10.447 Thread-6031 Start caching content...
10-07 16:07:10.445 5618-6038/at.tty_eli.app D//RequestProgressManager.java:82﹕ 16:07:10.453 Thread-6031 Sending progress WRITING_TO_CACHE
10-07 16:07:10.455 5618-6038/at.tty_eli.app D//SpiceServiceListenerNotifier.java:146﹕ 16:07:10.459 Thread-6031 Message queue is Handler (android.os.Handler) {42dfa580}
10-07 16:07:10.455 5618-5618/at.tty_eli.app V//DefaultRequestListenerNotifier.java:131﹕ 16:07:10.462 main Notifying 1 listeners of progress com.octo.android.robospice.request.listener.RequestProgress@42a3aa28
10-07 16:07:10.455 5618-6038/at.tty_eli.app D//LruCacheObjectPersister.java:74﹕ 16:07:10.467 Thread-6031 Put in lru cache for cacheKey234234
10-07 16:07:10.465 5618-6038/at.tty_eli.app D//RequestProgressManager.java:82﹕ 16:07:10.473 Thread-6031 Sending progress COMPLETE
10-07 16:07:10.475 5618-6038/at.tty_eli.app D//SpiceServiceListenerNotifier.java:146﹕ 16:07:10.480 Thread-6031 Message queue is Handler (android.os.Handler) {42dfa580}
10-07 16:07:10.475 5618-5618/at.tty_eli.app V//DefaultRequestListenerNotifier.java:131﹕ 16:07:10.483 main Notifying 1 listeners of progress com.octo.android.robospice.request.listener.RequestProgress@42a977a0
10-07 16:07:10.475 5618-6038/at.tty_eli.app D//SpiceServiceListenerNotifier.java:146﹕ 16:07:10.488 Thread-6031 Message queue is Handler (android.os.Handler) {42dfa580}
10-07 16:07:10.485 5618-5618/at.tty_eli.app V//DefaultRequestListenerNotifier.java:166﹕ 16:07:10.491 main Notifying 1 listeners of request success
10-07 16:07:10.485 5618-5618/at.tty_eli.app V//DefaultRequestListenerNotifier.java:172﹕ 16:07:10.494 main Notifying ReverseStringRequestListener
10-07 16:07:10.485 5618-5618/at.tty_eli.app V/AppointmentFragment_﹕ onDataReady
10-07 16:07:10.495 5618-6038/at.tty_eli.app V//RequestProgressManager.java:161﹕ 16:07:10.503 Thread-6031 Removing CachedSpiceRequest [requestCacheKey=cacheKey234234, cacheDuration=50000, spiceRequest=at.tty_eli.app.network.ConfigFeedRequest@42c24c50] size is 1
10-07 16:07:10.505 5618-6038/at.tty_eli.app D//RequestProgressManager.java:91﹕ 16:07:10.508 Thread-6031 Sending all request complete.
10-07 16:07:10.515 5618-6038/at.tty_eli.app V//SpiceService.java:495﹕ 16:07:10.520 Thread-6031 Pending requests : 0
10-07 16:07:10.515 5618-6038/at.tty_eli.app D//SpiceServiceListenerNotifier.java:146﹕ 16:07:10.524 Thread-6031 Message queue is Handler (android.os.Handler) {42dfa580}
10-07 16:07:10.545 5618-5618/at.tty_eli.app D/AbsListView﹕ unregisterIRListener() is called
10-07 16:07:10.565 5618-6038/at.tty_eli.app D//DefaultRequestRunner.java:295﹕ 16:07:10.569 Thread-6031 It tooks 3828 ms to process request CachedSpiceRequest [requestCacheKey=cacheKey234234, cacheDuration=50000, spiceRequest=at.tty_eli.app.network.ConfigFeedRequest@42c24c50].
I guess the problem comes from the fact that each fragment manages its own SpiceManager.
If so, the SpiceManager is stopped and a new one is restarted when you press home and resume the app. Then they start a different spice service. As you service seems to have a memory cache only, it is not filled anymore with you value.
But it doesn't explain why the same manager can be static and that works.
Can you try with a real disk cache ?
If you want the SpiceManager to be shared by fragments, manage it at the activity level and pass it to the fragments.
S. Le 2014-10-08 14:49, "Stephan Petzl" [email protected] a écrit :
As long as I am staying in the same fragment the cache works perfectly fine. BUT as soon as I am switching the app to the background and then reloading the data onResume(), the cache is not valid anymore and a network connection is made.
Here is my code (in fragment.onResume()):
protected void loadData(final OnDataLoadListener onDataLoadListener) { final ReverseStringRequestListener listener = new ReverseStringRequestListener(onDataLoadListener); final String cacheKey = "cacheKey234234"; final ConfigFeedRequest request = new ConfigFeedRequest("http://app.tty-eli.com/index.php?id=3"); getSpiceManager().getFromCacheAndLoadFromNetworkIfExpired(request, cacheKey, DurationInMillis.ONE_SECOND * 50, listener); }
Any ideas why this might happen? I am creating the SpiceManager in the class header of the fragment like that:
private SpiceManager spiceManager = new SpiceManager(InMemorySpiceService.class);
Here is the log:
10-07 16:07:06.595 5618-5618/at.tty_eli.app D//SpiceManager.java:212﹕ 16:07:06.606 main SpiceManager started. 10-07 16:07:06.605 5618-5618/at.tty_eli.app V/AppointmentFragment_﹕ onResume 10-07 16:07:06.605 5618-5618/at.tty_eli.app D//SpiceManager.java:489﹕ 16:07:06.619 main adding request to request queue 10-07 16:07:06.605 5618-5618/at.tty_eli.app D/AbsListView﹕ onVisibilityChanged() is called, visibility : 0 10-07 16:07:06.605 5618-5618/at.tty_eli.app D/AbsListView﹕ unregisterIRListener() is called 10-07 16:07:06.615 5618-6034/at.tty_eli.app V//SpiceManager.java:1191﹕ 16:07:06.623 SpiceManagerThread 2 Binding to service. 10-07 16:07:06.625 5618-5618/at.tty_eli.app D//SpiceService.java:134﹕ 16:07:06.631 main SpiceService instance created. 10-07 16:07:06.625 5618-5618/at.tty_eli.app D/AbsListView﹕ unregisterIRListener() is called 10-07 16:07:06.625 5618-6034/at.tty_eli.app V//SpiceManager.java:1197﹕ 16:07:06.633 SpiceManagerThread 2 Binding to service succeeded. 10-07 16:07:06.625 5618-6034/at.tty_eli.app D//SpiceManager.java:1245﹕ 16:07:06.637 SpiceManagerThread 2 Waiting for service to be bound. 10-07 16:07:06.645 5618-5618/at.tty_eli.app V//SpiceService.java:506﹕ 16:07:06.656 main Pending requests : 0 10-07 16:07:06.645 5618-5618/at.tty_eli.app V//SpiceService.java:508﹕ 16:07:06.658 main Stop foreground 10-07 16:07:06.655 5618-5618/at.tty_eli.app D//SpiceServiceListenerNotifier.java:33﹕ 16:07:06.662 main Message Queue starting 10-07 16:07:06.655 5618-5618/at.tty_eli.app D//SpiceManager.java:1088﹕ 16:07:06.664 main Bound to service : InMemorySpiceService 10-07 16:07:06.665 5618-6034/at.tty_eli.app D//SpiceManager.java:1252﹕ 16:07:06.673 SpiceManagerThread 2 Bound ok. 10-07 16:07:06.665 5618-6034/at.tty_eli.app D//SpiceManager.java:286﹕ 16:07:06.678 SpiceManagerThread 2 Sending request to service : CachedSpiceRequest 10-07 16:07:06.675 5618-6034/at.tty_eli.app D//RequestProcessor.java:63﹕ 16:07:06.683 SpiceManagerThread 2 Adding request to queue 1121951496: CachedSpiceRequest [requestCacheKey=cacheKey234234, cacheDuration=50000, spiceRequest=at.tty_eli.app.network.ConfigFeedRequest@42c24c50] size is 0 10-07 16:07:06.675 5618-6034/at.tty_eli.app D//RequestProcessor.java:85﹕ 16:07:06.689 SpiceManagerThread 2 Adding entry for type class at.tty_eli.app.network.ConfigFeedResponse and cacheKey cacheKey234234. 10-07 16:07:06.685 5618-6034/at.tty_eli.app D//RequestProgressManager.java:61﹕ 16:07:06.692 SpiceManagerThread 2 Request was added to queue. 10-07 16:07:06.685 5618-6034/at.tty_eli.app D//SpiceServiceListenerNotifier.java:146﹕ 16:07:06.695 SpiceManagerThread 2 Message queue is Handler (android.os.Handler) {42dfa580} 10-07 16:07:06.685 5618-5618/at.tty_eli.app D//SpiceServiceListenerNotifier.java:175﹕ 16:07:06.698 main Processing request added: CachedSpiceRequest [requestCacheKey=cacheKey234234, cacheDuration=50000, spiceRequest=at.tty_eli.app.network.ConfigFeedRequest@42c24c50] 10-07 16:07:06.695 5618-6034/at.tty_eli.app D//RequestProgressManager.java:82﹕ 16:07:06.703 SpiceManagerThread 2 Sending progress PENDING 10-07 16:07:06.695 5618-6034/at.tty_eli.app D//SpiceServiceListenerNotifier.java:146﹕ 16:07:06.708 SpiceManagerThread 2 Message queue is Handler (android.os.Handler) {42dfa580} 10-07 16:07:06.705 5618-5618/at.tty_eli.app V//DefaultRequestListenerNotifier.java:131﹕ 16:07:06.710 main Notifying 1 listeners of progress com.octo.android.robospice.request.listener.RequestProgress@42c24c88 10-07 16:07:06.705 5618-6038/at.tty_eli.app D//DefaultRequestRunner.java:83﹕ 16:07:06.714 Thread-6031 Processing request : CachedSpiceRequest [requestCacheKey=cacheKey234234, cacheDuration=50000, spiceRequest=at.tty_eli.app.network.ConfigFeedRequest@42c24c50] 10-07 16:07:06.705 5618-6034/at.tty_eli.app V//SpiceService.java:506﹕ 16:07:06.713 SpiceManagerThread 2 Pending requests : 1 10-07 16:07:06.705 5618-6038/at.tty_eli.app D//DefaultRequestRunner.java:97﹕ 16:07:06.718 Thread-6031 Loading request from cache : CachedSpiceRequest [requestCacheKey=cacheKey234234, cacheDuration=50000, spiceRequest=at.tty_eli.app.network.ConfigFeedRequest@42c24c50] 10-07 16:07:06.715 5618-6038/at.tty_eli.app D//RequestProgressManager.java:82﹕ 16:07:06.720 Thread-6031 Sending progress READING_FROM_CACHE 10-07 16:07:06.715 5618-6038/at.tty_eli.app D//SpiceServiceListenerNotifier.java:146﹕ 16:07:06.727 Thread-6031 Message queue is Handler (android.os.Handler) {42dfa580} 10-07 16:07:06.715 5618-5618/at.tty_eli.app V//DefaultRequestListenerNotifier.java:131﹕ 16:07:06.729 main Notifying 1 listeners of progress com.octo.android.robospice.request.listener.RequestProgress@42b0d130 10-07 16:07:06.725 5618-6034/at.tty_eli.app V//SpiceService.java:508﹕ 16:07:06.716 SpiceManagerThread 2 Stop foreground 10-07 16:07:06.725 5618-6038/at.tty_eli.app D//LruCacheObjectPersister.java:47﹕ 16:07:06.732 Thread-6031 Miss from lru cache for cacheKey234234 10-07 16:07:06.725 5618-6038/at.tty_eli.app D//LruCacheObjectPersister.java:47﹕ 16:07:06.737 Thread-6031 Miss from lru cache for cacheKey234234 10-07 16:07:06.735 5618-6038/at.tty_eli.app D//DefaultRequestRunner.java:129﹕ 16:07:06.741 Thread-6031 Cache content not available or expired or disabled 10-07 16:07:06.745 5618-6038/at.tty_eli.app D//DefaultRequestRunner.java:148﹕ 16:07:06.751 Thread-6031 Calling netwok request. 10-07 16:07:06.745 5618-6038/at.tty_eli.app D//RequestProgressManager.java:82﹕ 16:07:06.755 Thread-6031 Sending progress LOADING_FROM_NETWORK 10-07 16:07:06.755 5618-6038/at.tty_eli.app D//SpiceServiceListenerNotifier.java:146﹕ 16:07:06.760 Thread-6031 Message queue is Handler (android.os.Handler) {42dfa580} 10-07 16:07:06.755 5618-5618/at.tty_eli.app V//DefaultRequestListenerNotifier.java:131﹕ 16:07:06.763 main Notifying 1 listeners of progress com.octo.android.robospice.request.listener.RequestProgress@42c11c38 10-07 16:07:10.435 5618-6038/at.tty_eli.app D//DefaultRequestRunner.java:151﹕ 16:07:10.442 Thread-6031 Network request call ended. 10-07 16:07:10.435 5618-6038/at.tty_eli.app D//DefaultRequestRunner.java:171﹕ 16:07:10.447 Thread-6031 Start caching content... 10-07 16:07:10.445 5618-6038/at.tty_eli.app D//RequestProgressManager.java:82﹕ 16:07:10.453 Thread-6031 Sending progress WRITING_TO_CACHE 10-07 16:07:10.455 5618-6038/at.tty_eli.app D//SpiceServiceListenerNotifier.java:146﹕ 16:07:10.459 Thread-6031 Message queue is Handler (android.os.Handler) {42dfa580} 10-07 16:07:10.455 5618-5618/at.tty_eli.app V//DefaultRequestListenerNotifier.java:131﹕ 16:07:10.462 main Notifying 1 listeners of progress com.octo.android.robospice.request.listener.RequestProgress@42a3aa28 10-07 16:07:10.455 5618-6038/at.tty_eli.app D//LruCacheObjectPersister.java:74﹕ 16:07:10.467 Thread-6031 Put in lru cache for cacheKey234234 10-07 16:07:10.465 5618-6038/at.tty_eli.app D//RequestProgressManager.java:82﹕ 16:07:10.473 Thread-6031 Sending progress COMPLETE 10-07 16:07:10.475 5618-6038/at.tty_eli.app D//SpiceServiceListenerNotifier.java:146﹕ 16:07:10.480 Thread-6031 Message queue is Handler (android.os.Handler) {42dfa580} 10-07 16:07:10.475 5618-5618/at.tty_eli.app V//DefaultRequestListenerNotifier.java:131﹕ 16:07:10.483 main Notifying 1 listeners of progress com.octo.android.robospice.request.listener.RequestProgress@42a977a0 10-07 16:07:10.475 5618-6038/at.tty_eli.app D//SpiceServiceListenerNotifier.java:146﹕ 16:07:10.488 Thread-6031 Message queue is Handler (android.os.Handler) {42dfa580} 10-07 16:07:10.485 5618-5618/at.tty_eli.app V//DefaultRequestListenerNotifier.java:166﹕ 16:07:10.491 main Notifying 1 listeners of request success 10-07 16:07:10.485 5618-5618/at.tty_eli.app V//DefaultRequestListenerNotifier.java:172﹕ 16:07:10.494 main Notifying ReverseStringRequestListener 10-07 16:07:10.485 5618-5618/at.tty_eli.app V/AppointmentFragment_﹕ onDataReady 10-07 16:07:10.495 5618-6038/at.tty_eli.app V//RequestProgressManager.java:161﹕ 16:07:10.503 Thread-6031 Removing CachedSpiceRequest [requestCacheKey=cacheKey234234, cacheDuration=50000, spiceRequest=at.tty_eli.app.network.ConfigFeedRequest@42c24c50] size is 1 10-07 16:07:10.505 5618-6038/at.tty_eli.app D//RequestProgressManager.java:91﹕ 16:07:10.508 Thread-6031 Sending all request complete. 10-07 16:07:10.515 5618-6038/at.tty_eli.app V//SpiceService.java:495﹕ 16:07:10.520 Thread-6031 Pending requests : 0 10-07 16:07:10.515 5618-6038/at.tty_eli.app D//SpiceServiceListenerNotifier.java:146﹕ 16:07:10.524 Thread-6031 Message queue is Handler (android.os.Handler) {42dfa580} 10-07 16:07:10.545 5618-5618/at.tty_eli.app D/AbsListView﹕ unregisterIRListener() is called 10-07 16:07:10.565 5618-6038/at.tty_eli.app D//DefaultRequestRunner.java:295﹕ 16:07:10.569 Thread-6031 It tooks 3828 ms to process request CachedSpiceRequest [requestCacheKey=cacheKey234234, cacheDuration=50000, spiceRequest=at.tty_eli.app.network.ConfigFeedRequest@42c24c50].
— Reply to this email directly or view it on GitHub https://github.com/stephanenicolas/robospice/issues/370.
I removed my comment with the static instance of spice manager again. It does not work as expected.
Then they start a different spice service.
I don't get this part. Isn't the whole point of using a service, exactly to have a decoupled instance which is not depending on the live cycle of activities and fragments? Why is instancing a new SpiceManager influencing the cache?
My Service looks like this:
package at.anne_eli.app.service;
import android.Manifest;
import android.app.Application;
import android.content.Context;
import android.content.pm.PackageManager;
import com.octo.android.robospice.SpiceService;
import com.octo.android.robospice.networkstate.NetworkStateChecker;
import com.octo.android.robospice.persistence.CacheManager;
import com.octo.android.robospice.persistence.ObjectPersister;
import com.octo.android.robospice.persistence.memory.CacheItem;
import com.octo.android.robospice.persistence.memory.LruCache;
import com.octo.android.robospice.persistence.memory.LruCacheObjectPersister;
import at.anne_eli.app.network.ConfigFeedResponse;
/**
* Created by stephan on 07.10.14.
*/
public class InMemorySpiceService extends SpiceService {
public InMemorySpiceService() {
super();
}
@Override
protected NetworkStateChecker getNetworkStateChecker() {
return new MyNetworkStateChecker();
}
@Override
public CacheManager createCacheManager(Application application) {
CacheManager manager = new CacheManager();
manager.addPersister(new MyPersister(ConfigFeedResponse.class, new LruCache(1024 * 1024)));
return manager;
}
class MyPersister extends LruCacheObjectPersister {
public MyPersister(Class clazz, LruCache
Just debugged a little further: Indeed, each time I switch from one fragment to another a new SpiceService and thus a new CacheManager is created. Can you tell me why this is happening?
I don't understand @Stephan Petzl, as service is like an activity. These things live and die and have a life cycle. There are no chances you can get a service to survive for ever. So, yes, every time you start a new spice manager it will start a new service. The only exception is that if a spice service is already started, your new spicemanager will use it, but this rarely happen and no one has a real control over it.
There is a true limitation in your approach when using a RAM only cache manager. This can be super fast and convenient but you don't persist the state of the cache if you don't write it somewhere.
So there are 2 solutions here :
- either you use a disk cache as intended in RS
- or you can use a small hack and use a cache manager in RAM only that is a singleton and reused by all your instances of your spice service. But even, then you will never be able to guarantee that this cache manager will always be there as android apps can be wiped out by the system at any time. This is a the core of android programming model : make apps transients so that they don't fill up the system memory for ever..
S.
2014-10-10 10:20 GMT-04:00 Stephan Petzl [email protected]:
Just debugged a little further: Indeed, each time I switch from one fragment to another a new SpiceService and thus a new CacheManager is created. Can you tell me why this is happening?
— Reply to this email directly or view it on GitHub https://github.com/stephanenicolas/robospice/issues/370#issuecomment-58662031 .
@stephanenicolas Thanks for your explanations! And I get it now: Since this is a bound service, it will be cleaned up by android as soon as there are no references to it anymore. That makes totally sense from a technical side of things. However, wouldn't you agree, that it's kind of counter-intuitive, that the whole caching is not working anymore as soon as you use the LruCacheObjectPersister and you pause and resume the app? (That's also how you have implemented it in your samples.) For me from a User perspective, it's not intuitive that the cache is not returning a cached object after I rotate the device- especially when I know that the big advantage of RoboSpice is that it runs in a service (which is decoupled from the activity live cycle).
I can totally see your point with saving the data to disc- but for my application I would really like to have a fast implementation, which delivers data from RAM instantly and only retrieves from disc when RAM is not available anymore. I don't want to criticize roboSpice- it's a wonderful piece of library- that's just my 2 cents of feedback.
@stoefln, In our application, we have extended the SpiceManager by adding our own execute method and implemented a singleton LruCache. This way, we are synchronously checking the LruCache before anything has been submitted to the SpiceService, giving us a considerable performance gain when there is a cache hit. This is a simple paradigm which improved responsiveness for us dramatically, but it adds "synchronicity" and is not part of the RoboSpice's underlying idea. However, if I understood your challenge correctly, it may help in your case.
Hi @Nikola Keskinov and @Stephan Petzl,
Stephan, from a user perspective I know it can be surprising but that is what Android programming is about : preserving resources through life cycles. Things live and die and free resources on Android.
So, I think it's really a better idea to stick to using a disk cache and use RAM caching with great care in RS and in Android in general. That's why RS provides so many options for disk caching data.
Adding a RAM cache is still possible. Personally I would prefer a singleton RAM cache to decorate/backed by a disk cache at the service level. But maybe @Nikola Keskinov's solution is a simpler .. I would need to see it in a PR to judge ;)
S.
2014-10-16 5:25 GMT-04:00 Nikola Keskinov [email protected]:
@stoefln https://github.com/stoefln, In our application, we have extended the SpiceManager by adding our own execute method and implemented a singleton LruCache. This way, we are synchronously checking the LruCache before anything has been submitted to the SpiceService, giving us a considerable performance gain when there is a cache hit. This is a simple paradigm which improved responsiveness for us dramatically, but it adds "synchronicity" and is not part of the RoboSpice's underlying idea. However, if I understood your challenge correctly, it may help in your case.
— Reply to this email directly or view it on GitHub https://github.com/stephanenicolas/robospice/issues/370#issuecomment-59335808 .
Hi @stephanenicolas,
The solution we have is still too messy and coupled with our app, but I do plan to generalize and integrate it into RoboSpice as a nice PR one day. However, the idea of it, in simplest terms is:
// may not be syntactically correct as it is an excerpt of a bigger class with out-of-this-context code
public class APICacheSpiceManager extends SpiceManager {
// singleton memory cache, extension/wrapper of Android's LruCache
private final APICache cache = APICache.getInstance();
public <T, R> void fetch(Context context, AbstractSpiceRequest<T, R> req, Object cacheKey, long cacheDuration, RequestListener<T> listener) {
T result;
if (cacheKey != null) {
result = (T) cache.get(cacheKey, cacheDuration);
if (result != null) {
Log.d("FETCH", ms(time) + "Instantly loading request from L1 cache: " + req);
listener.onRequestSuccess(result);
return;
} else {
// CacheFillerListener is going to save the result in our memory cache, storing the timestamp of the creation as well (for cache duration)
listener = new CacheFillerListener<>(cache, cacheKey, listener);
CacheManager cacheManager = getCacheManager((Application) context.getApplicationContext());
result = cacheManager.loadDataFromCache(req.getResultType(), cacheKey, cacheDuration);
if (result != null) {
Log.d("FETCH", ms(time) + "Instantly request loaded from L2 cache: " + req);
// send cached result immediately and return
listener.onRequestSuccess(result);
return;
} else {
Log.d("FETCH", "Executing Spice request: " + req + " ON " + this);
super.execute(req, cacheKey, DurationInMillis.ALWAYS_EXPIRED, listener);
}
}
} else {
// use network etc.
}
}
If there is a cache hit either in memory or disk cache (L1 or L2), no RoboSpice mechanism is triggered (request queueing, spice service, asynchronicity...). Instead, request listener's onSuccess will be immediately executed. According to our performance tests, there was a great improvement of using the cache this way, compared to the async use via service.
@nkeskinov thanks for sharing your code! I think it would be great if we could find a generic concept which could go into the RoboSpice code. Would be happy to participate in your PR!