-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNetworkBoundResource.java
107 lines (82 loc) · 3.79 KB
/
NetworkBoundResource.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
public abstract class NetworkBoundResource<Result, Request> {
private AppExecutors appExecutors;
private MediatorLiveData<Resource<Result>> results = new MediatorLiveData<>();
public NetworkBoundResourceSimple(AppExecutors appExecutors) {
this.appExecutors = appExecutors;
init();
}
private void init() {
results.setValue(Resource.loading(null));
final LiveData<Result> dbSource = LiveDataReactiveStreams.fromPublisher(loadFromDb());
results.addSource(dbSource, result -> {
results.removeSource(dbSource);
if (shouldFetch(result)) {
fetchFromNetwork(dbSource);
} else {
results.addSource(dbSource, result1 -> setValue(Resource.success(result1)));
}
});
}
private void fetchFromNetwork(final LiveData<Result> dbSource) {
results.addSource(dbSource, result -> setValue(Resource.loading(result)));
final LiveData<ApiResponse<Request>> apiResponse = LiveDataReactiveStreams.fromPublisher(
createCall()
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.map(response -> new ApiResponse<Request>().create(response))
.onErrorReturn(throwable -> new ApiResponse<Request>().create(throwable))
);
results.addSource(apiResponse, requestObjectApiResponse -> {
results.removeSource(dbSource);
results.removeSource(apiResponse);
if (requestObjectApiResponse instanceof ApiResponse.ApiSuccessResponse) {
appExecutors.diskIO().execute(() -> {
saveCallResult((((ApiResponse.ApiSuccessResponse<Request>) requestObjectApiResponse).getBody()));
appExecutors.mainThread().execute(new Runnable() {
@Override
public void run() {
results.addSource(LiveDataReactiveStreams.fromPublisher(loadFromDb()), new Observer<Result>() {
@Override
public void onChanged(@Nullable Result result) {
setValue(Resource.success(result));
}
});
}
});
});
} else if (requestObjectApiResponse instanceof ApiResponse.ApiEmptyResponse) {
appExecutors.mainThread().execute(() -> results.addSource(LiveDataReactiveStreams.fromPublisher(loadFromDb()), new Observer<Result>() {
@Override
public void onChanged(@Nullable Result result) {
setValue(Resource.success(result));
}
}));
} else if (requestObjectApiResponse instanceof ApiResponse.ApiErrorResponse) {
results.addSource(dbSource, result -> setValue(
Resource.error(
result,
((ApiResponse.ApiErrorResponse<Request>) requestObjectApiResponse).getMsg()
)
));
}
});
}
private void setValue(Resource<Result> newValue) {
if (results.getValue() != newValue) {
results.setValue(newValue);
}
}
@WorkerThread
public abstract void saveCallResult(@NonNull Request item);
@MainThread
public abstract boolean shouldFetch(@Nullable Result data);
@NonNull
@MainThread
public abstract Flowable<Result> loadFromDb();
@NonNull
@MainThread
public abstract Flowable<Response<Request>> createCall();
public final LiveData<Resource<Result>> getAsLiveData() {
return results;
}
}