Retrieving data from the cache before executing a network request using RoboSpice

I am using RoboSpice and want to have the following behavior in my application:

  • The user starts an operation that requires data from the server.
  • spiceManager checks to see if data is cached by returning, if so.
  • regardless of whether caching data was saved, a request to the server is made
  • When fresh data comes from the server, I update it with (if activity is still active)

It should be something like a facebook application: when you open it, you instantly see the outdated timeline and end up with an update.

At first I thought it spiceManager.getFromCacheAndLoadFromNetworkIfExpired()was a good way to achieve this, but if the data is cached and valid, it just returns the cache without asking the network right after it. I have tried this both with DurationInMillis.ALWAYS_EXPIREDand DurationInMillis.ALWAYS_RETURNED.

Should I use getFromCache()to retrieve cached data and then from onRequestSuccess()invoke spiceManager.execute()with always_expired as a parameter? Or is there a better / easier way to do this?

Thanks in advance for your help!

[edit] These links can add to the discussion: https://groups.google.com/forum/#!topic/robospice/n5ffupPIpkE/discussion https://groups.google.com/forum/#!topic/robospice/LtoqIXk5JpA

+4
source share
3 answers

:

  • ,
  • , . , .

SpecialOffersRequest request = new SpecialOffersRequest();
spiceManager.getFromCache(SpecialOffer.List.class, request.getCacheKey(), ALWAYS_RETURNED, new SpecialOffersRequestListener());
spiceManager.execute(request, request.getCacheKey(), request.getCacheExpiryDuration(), new SpecialOffersRequestListener());

, SpecialOffersRequestListener get-from-cache, get-from-network. , (. dataInCache) - " ", - :

private final class SpecialOffersRequestListener implements RequestListener<SpecialOffer.List> {
    @Override
    public void onRequestFailure(SpiceException spiceException) {
        if (spiceException instanceof NoNetworkException && dataInCache) {
            // Ignore network problems if there is some data in the cache.
            return;
        }

        ActionHelper.showError(getActivity(), "Failed to load special offers.", spiceException);
    }

    @Override
    public void onRequestSuccess(SpecialOffer.List result) {
        dataInCache = true;
        ...
    }
}
+3

Aka_sh : ( , Android), dataInCache false, (, ).

- SpiceManager isDataInCache getDateOfDataInCache, 1.4.6-SNAPSHOT. , , .

, : , Future<Boolean>/Future<Data>, , ( , ), Future.get(), :

spiceManager.isDataInCache(MyCachedObj.class, cacheKey, DurationInMillis.ALWAYS_RETURNED).get();
+2

. , , A , B , . A, ( 2).

1: , PendingRequestListener onStart. 2, PendingRequestListener pendingRequest robospice .

@Override
public void onStart() {
    super.onStart();
    FragmentPostActivity.spiceManagerPlaces.addListenerIfPending(Post.class, "POSTS", pendingRequestListener);
}

2: PendingRequestListener.

PendingRequestListener pendingRequestListener = new PendingRequestListener() {
    @Override 
    public void onRequestNotFound() {
    //This is when no request is found at all - this method will be triggered. Notice that I have
    //placed this method within the onStart method which means that when your app onStarts - when you 
    //click on the app icon on your phone, this method will actually be triggered so therefore it will first
    //get the data from cache by using the cacheKey "POSTS", then it will trigger a separate spiceRequest for network
    //operations to fetch the data from the server. Notice that the second spiceRequest does not have a cacheKey.
    //The reason is that we are not going to return back the results of the network operations - we will return
    //the results of our cache that we will manually create at a later stage
        PostSpiceRequest postSpiceRequest = new PostSpiceRequest(getActivity(), postid);
        FragmentPostActivity.spiceManagerPlaces.getFromCache(EmbedPost.class, "POSTS", DurationInMillis.ONE_WEEK, new PostListener());
        FragmentPostActivity.spiceManagerPlaces.execute(PostSpiceRequest,new PostListener());
    }

    @Override
    public void onRequestFailure(SpiceException spiceException) {
    //This is if your request failed when you navigate back to Activity A from Activity B
        Log.e("PendingRequestRS", "request failed for pending requests");

    }

    @Override
    public void onRequestSuccess(Object o) {
        //This is if your request succeed when you navigate back to Activity A from Activity B
        Log.e("PendingRequestRS", "pending request successful");
        FragmentPostActivity.spiceManagerPlaces.getFromCache(Post.class, "POSTS", DurationInMillis.ONE_WEEK, new PostListener());
    }
};

STEP 3: Add a manual data caching method so that it can be restored when your application starts up again. The method below counts up to 20 messages, and then puts them in the cache. If it is less than 20 messages, it will cache up to this amount.

@Override
public void onPause() {
    super.onPause();
    //If you are using a spiceManager from your activity class, you will needs to put this code into onPause and not in onStop. 
    //Inside your activity, you would have stopped the spicemanager in onStop, which means that your cache would not be stored
    //at all.
    //If you are using a spiceManager in your fragment class, you are free to put this code within your onStop method but make
    //sure that it is place in front of the spiceManager.onStop() so that the method will execute before it spicemanager is stopped

    LinkedList<Post> cachedPosts = new LinkedList<>();
    if (posts.size() > 20) {
        for (int i = 0; i <= 20; i++) {
            cachedPosts.add(posts.get(i));
        }
    } else {
        for (int i = 0; i < posts.size(); i++) {
            cachedPosts.add(posts.get(i));
        }
    }
    PostActivity.spiceManager.removeDataFromCache(Post.class, "POSTS");
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                FragmentPostActivity.spiceManagerPlaces.putDataInCache("POSTS", cachedPosts);
            } catch (CacheSavingException e) {
                e.printStackTrace();
            } catch (CacheCreationException e) {
                e.printStackTrace();
            }
        }
    }).start();
}

I hope I shed some light on the subject of using Robospice, since there is very little documentation on how to do this.

0
source

Source: https://habr.com/ru/post/1526590/


All Articles