我阅读了本指南:https://developer.android.com/jetpack/docs/guide 并尝试在这种情况下使用存储库模式:
通过翻新库 app向服务器/get/user
发出GET请求,服务器的响应可能是这样的(状态200):
{
"user": {"name" : "Jack", "id": "99"},
"status": true
}
或类似这样(状态200):
{ "status": false, "message": "Some error here"}
或例如500错误。
我的UserFragment
应该显示对话框,具体取决于服务器响应:如果一切正常-正常消息,如果状态为false-来自api响应的错误消息,如果500-其他错误消息。
我的POJO模型如下:
public class User {
private String id;
private String name;
// getters and setters omitted
}
public class ApiResponse {
private User user;
private Boolean status;
private String message;
// getters and setters omitted
}
我应该如何以存储库模式处理它?</ p>
我更喜欢1,因为对我来说更清楚了,但是我的问题-如何处理从服务器返回的状态和消息字段,并需要在Fragment中显示数据。
答案 0 :(得分:1)
这取决于您计划在Fragment
上显示哪些信息。
如果网络出现问题,您是否会向用户显示错误消息?还是只显示“找不到用户”消息,您会感到高兴。
您打算向用户显示的数据应进入ViewModel
。
如果要直接显示来自Api的错误消息,请将其传递给ViewModel
。
如果仅打算显示用户,则将其传递给ViewModel
。在这种情况下,错误消息只能被概括。
答案 1 :(得分:1)
这是我的操作方式:
存储库:
prival final MutableLiveData<User> userData = new MutableLiveData<>();
public void getUser(){
//post user to userData when you got response from the server
}
public LiveData<User> getUserData(){ return userData; }
ViewModel:
public LiveData<User> user = Repository.getInstance().getUserData();
在这种情况下,您的viewModel不会每次都创建liveData,它将从存储库中获取liveData。此外,您将在您的仓库中加载数据,因此您不必经常触发调用。
如果您需要了解每个呼叫状态,请使用liveData和response obj livedata内的NetworkState枚举创建类似DataSource Holder对象之类的东西
这是我的RemoteDataSource:
public class RemoteDataSource<T> {
private final MutableLiveData<NetworkState> networkState = new MutableLiveData<>();
private final MutableLiveData<T> data = new MutableLiveData<>();
private final Action action;
private String errorMessage;
public RemoteDataSource(Action action) {
networkState.postValue(NetworkState.Default);
this.action = action;
}
public MutableLiveData<NetworkState> getNetworkState() {
return networkState;
}
public void setIsLoading() {
networkState.postValue(NetworkState.Loading);
}
public void setDefault() {
networkState.postValue(NetworkState.Default);
}
public void setIsLoaded(T data) {
networkState.postValue(NetworkState.Loaded);
this.data.postValue(data);
}
public void setFailed(@NonNull String errorMessage) {
this.errorMessage = errorMessage;
networkState.postValue(NetworkState.Failed);
}
public String getErrorMessage() {
return errorMessage;
}
public MutableLiveData<T> getData() {
return data;
}
public void executeLoad() {
if (action != null) {
try {
action.run();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
答案 2 :(得分:1)
我使用存储库模式来保持简单的动作来检索所需的信息,没有什么真正复杂的:
/**
* Repository that exposes DataSources and Observables for loading data from local/network sources
* Repository also exposes Subjects that inform about state of the calls
*/
class ExampleCitiesRepository @Inject constructor(private val apiCities: ExampleCitiesApiEndpointsInterface,
private val daoCities: ExampleCityDao) {
fun citiesDataSourceFactory(compositeDisposable: CompositeDisposable) = CitiesDataSourceFactory(apiCities, compositeDisposable)
fun citiesFromNetwork() =
apiCities.getCitiesList().mapResponseList(mapper = { ExampleCityModel(it) })
fun pagedCitiesFromDatabase() = daoCities.citiesPagedById().map { ExampleCityModel(it) }
fun citiesFromDatabase() = daoCities.citiesById().map { it.map { ExampleCityModel(it) } }!!
fun saveAllCitiesToDatabase(cities: Collection<ExampleCityModel>) = Single.fromCallable { daoCities.insertOrReplaceAll(cities.map { ExampleCityDbModel(it) }) }!!
fun deleteAllCitiesFromDatabase() = Single.fromCallable { daoCities.deleteAll() }!!
}
此外,我正在将“后端模型”映射到应用程序模型(我不喜欢创建一个模型,因为后端可以更改其模型,然后迫使我们也更改模型)。就是这样,我可以获取要使用的模型,可以使用Rx的dispose结束通话,也可以使用此获取错误代码或消息。
ViewModels与此配合良好,因为当不再需要viewModel时我们可以获取回调,然后我们可以取消网络调用。如果没有打开应用程序,我们可以继续进行网络呼叫,因为实时数据可以确保在正确的时间将数据从ViewModel传递到View
答案 3 :(得分:0)
使用翻新,
您可以在回调类中获得响应,
您必须创建一个扩展该类的新类,
library(dplyr)
df %>% mutate(A=hours-lag(hours), B=if_else(is.na(A) | A!=-23,0,1), date=181010+cumsum(B==1))
#%>% select(-A,-B) #If you don't need them
time.sub hms hours A B date
1 23:59:53 23H 59M 53S 23 NA 0 181010
2 23:59:55 23H 59M 55S 23 0 0 181010
3 23:59:57 23H 59M 57S 23 0 0 181010
4 23:59:59 23H 59M 59S 23 0 0 181010
5 0:0:1 1S 0 -23 1 181011
6 0:0:3 3S 0 0 0 181011
别忘了覆盖onFailure。