Instead of showing an empty screen while waiting for a network response, why not load the latest successful response from storage?
- Responses are saved in device storage & RAM
- No extra logic, only
Call<T>
becomesSmartCall<T>
- Extend your own adapters for other caching strategies
- Add SmartCache to Gradle dependencies, and JitPack to repos:
repositories {
maven { url "https://jitpack.io" }
// ^^^^^^^^^^^^^^^^^^^ Add this!
}
dependencies {
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.github.fikisipi:SmartCache:2.9.0'
// ^^^^^^^^^^^^^^^^^^^ Add this!
}
- Add
SmartCallFactory
to your RetrofitBuilder
(wherethis
is an Activity/Context):
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://your-api.org")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(SmartCallFactory.createBasic(this))
// ^^^^^^^^^^^^^^^^ Add this!
.build();
- Replace
Call<T>
withSmartCall<T>
and you are done ✔️.
public interface GitHubService {
@GET("/users/{user}/repos")
SmartCall<List<Repo>> listRepos(@Path("user") String user);
// ^^^^^^^^^ Rename `Call` to `SmartCall`
}
Every enqueue()
callback is fired with preloaded data before the network invokes the callback. You can check which is which using
SmartCache.isResponseFromNetwork(response)
:
new Callback<YourModel>() {
@Override
public void onResponse(Call<YourModel> call, Response<YourModel> response) {
if(SmartCache.isResponseFromNetwork(response)) {
Most apps shouldn't cache stateful routes like POST/PUT
so by default only GET
routes are cached.
You can change this by supplying filter: (Request) -> bool
when creating the factory
SmartCallFactory.createBasic(this, filter)
.
Each interface CachingSystem
now has void clearCache()
to delete the cache. By default,
SmartCache uses BasicCaching
as a LRU system, so clearing can be done like this:
BasicCaching.buildFromContext(getApplicationContext()).clearCache();
💻 Check the demo app for these examples.
For a complete example check demoapp/.
One request corresponds to two responses: a cache response and a network response. Loading content from your phone is faster than loading from network; therefore your app will show stale content while waiting for a fresh network response. (Note: If the network response comes first, cache won't happen.)
Help needed from contributors:
- Make it work with RxJava
- Implement a pool of threads
Copyright 2015-2021 Filip Dimitrovski
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.