-
Notifications
You must be signed in to change notification settings - Fork 1
/
BaseMergeDataResource.kt
122 lines (108 loc) · 4.37 KB
/
BaseMergeDataResource.kt
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package com.hudson.wanandroid.data.repository.base
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.google.gson.Gson
import com.hudson.wanandroid.data.common.AppExecutor
import com.hudson.wanandroid.data.common.mergecall.MergeData
import com.hudson.wanandroid.data.db.DataWrapperDao
import retrofit2.Response
import java.lang.reflect.ParameterizedType
/**
* 多个请求可以合并的Source
* Created by Hudson on 2020/7/22.
*/
abstract class BaseMergeDataResource<ResultType, RequestType: MergeData<*,*>>(
dataWrapperDao: DataWrapperDao,
appExecutor: AppExecutor
): BaseNetworkBoundResource<ResultType, RequestType>(dataWrapperDao, appExecutor){
protected var stashNetworkData: Response<RequestType>? = null
final override fun saveCallResult(item: RequestType) {
if(!item.networkData1Empty){
saveFirstData(item.data1)
}
if(!item.networkData2Empty){
saveSecondData(item.data2)
}
}
final override fun loadFromDb(): LiveData<ResultType> {
val mutableLiveData = MutableLiveData<ResultType>()
appExecutor.ioExecutor.execute{
val clazz = getRequestClass()
val mergeDataType = clazz.genericSuperclass as ParameterizedType
// MergeData types
val firstDataType = mergeDataType.actualTypeArguments[0] as Class<*>
val secondDataType = mergeDataType.actualTypeArguments[1] as Class<*>
// 查看是否存在网络数据返回204或空的情况,如果存在,确定内部是否有部分新数据,有则使用
val firstData = tryToGetValidFirstData() ?: loadFirstDataFromDb(firstDataType)
val secondData = tryToGetValidSecondData() ?: loadSecondDataFromDb(secondDataType)
val mergeData = createTargetMergeDataInstance(firstData, secondData)
mutableLiveData.postValue(transform(mergeData))
// 判断在MergeData是空数据的情况下,是否要刷新数据到数据库,因为可能只是其中一个数据为空导致的
if(needSaveResult()){
saveCallResult(mergeData)
}
}
return mutableLiveData
}
protected abstract fun createTargetMergeDataInstance(data1: Any?, data2: Any?): RequestType
/**
* 在网络请求返回数据存在204或空的情况下,
* 如果内部有部分数据是从网络上更新下来的,
* 那么需要刷回数据库中
*/
private fun needSaveResult(): Boolean{
return stashNetworkData?.isSuccessful == true &&
stashNetworkData?.code() == 204 &&
(stashNetworkData?.body()?.isDataFresh() == true)
}
private fun tryToGetValidFirstData() :Any?{
if(stashNetworkData?.isSuccessful == true && stashNetworkData?.code() == 204){
return if(stashNetworkData?.body()?.networkData1Empty == false){
stashNetworkData!!.body()!!.data1
}else{
null
}
}
return null
}
private fun tryToGetValidSecondData() :Any?{
if(stashNetworkData?.isSuccessful == true && stashNetworkData?.code() == 204){
return if(stashNetworkData?.body()?.networkData2Empty == false){
stashNetworkData!!.body()!!.data2
}else{
null
}
}
return null
}
override fun stashNetworkData(response: Response<RequestType>) {
super.stashNetworkData(response)
stashNetworkData = response
}
abstract fun loadFirstDataFromDb(clazz: Class<*>): Any?
abstract fun loadSecondDataFromDb(clazz: Class<*>): Any?
abstract fun saveFirstData(data: Any?)
abstract fun saveSecondData(data: Any?)
protected fun loadDataWrapperFromDb(clazz: Class<*>, identityInfo: String): Any?{
val wrapper = loadDataWrapper(
clazz,
dataWrapperDao,
identityInfo
)
//if one of MergeData is expired, the data is expired
checkDataExpire(wrapper)
return wrapper?.content?.run {
Gson().fromJson(this, clazz)
}
}
protected fun saveDataCommon(data: Any?, identityInfo: String){
data?.apply {
saveDataWrapper(
data.javaClass,
data,
dataWrapperDao,
identityInfo
)
}
}
}