onChanged() 在 HttpLoggingInterceptor 记录网络响应之前触发
onChanged() is triggered before the network response is logged by the HttpLoggingInterceptor
我正在尝试掌握 Android 中的 MVVM 架构,并且正在为此开发一个示例应用程序。我暂时避免使用 Repository class,它避免了关注点分离,但我想先更好地理解 ViewModel 和 LiveData。我有一个片段,我在其中使用改造和 viewmodel 实例进行网络调用。然后使用相同的 viewmodel 对象进行相同的调用,但参数值不同。现在 onChanged 被触发,当我记录响应时(使用 log.d),我在其中得到了旧的响应。在几毫秒的延迟之后,HttpLoggingInterceptor 记录新的响应。我已经尝试了很多东西,但我无法弄清楚发生了什么。在搜索这个问题时,我发现了这个:,但我不明白如何实现给定的答案。
代码:
Api接口
public interface ApiInterface {
@GET("fetch")
Call<String> fetchData(@Query("param1") String param1,
@Query("param2") String param2,
@Query("param3") String param3,
@Query("param4") String param4,
@Query("param5") String param5);
ViewModelData
public class ViewModelData extends ViewModel {
private MutableLiveData<String> data = new MutableLiveData<>();
private final String TAG = getClass().getSimpleName();
public LiveData<String> getData(String param1, String param2, String param3, String param4,
String param5){
loadData(param1, param2, param3, param4, param5);
return data;
}
private void loadData(String param1, String param2, String param3, String param4,
String param5){
Retrofit retrofit = HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okHttpClientGet = new OkHttpClient.Builder()
.addInterceptor(logging)
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(ScalarsConverterFactory.create())
.client(okHttpClientGet)
.build();
ApiInterface apiInterface = retrofit.create(ApiInterface.class);
Call<String> call = apiInterface.fetchData(param1, param2, param3, param4, param5);
call.enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
if(response.isSuccessful()){
Log.v(TAG, "onResponse: " + response.body());
data.postValue(response.body());
}else{
try {
String errorBody = response.errorBody().string();
Log.e(TAG, "onResponse: " + errorBody);
data.postValue(errorBody);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void onFailure(Call<String> call, Throwable t) {
Log.e(TAG, "onFailure: " + t.getMessage());
}
});
}
FragmentTest(这是我定义的一个函数,点击一个按钮就会被调用)
viewmodelData.getData("param1", "param2", "param3",
"param4", "param5")
.observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(String s) {
Log.v("TAG", "onChanged: " + s);
Gson gson = new Gson();
JsonObject root = gson.fromJson(s, JsonObject.class);
//parsing response...
}
});
ViewModel 实例已创建为:
viewmodelData = new ViewModelProvider(this).get(ViewModelData.class);
我很感激任何帮助,因为我已经坚持了一段时间了。
您的流程正在为同一个 LiveData 添加多个观察者,这可能会导致您看到的问题。
在每次单击按钮时,您都会(再次)观察 getData() 返回的 LiveData 对象。
将您的 getData 方法更改为:
public LiveData<String> getData() {
return data;
}
并使您的 loadData 方法 public:
public void loadData(String param1, String param2, String param3, String param4, String param5) {
...
}
在您片段的 onCreateView() 中为您的 LiveData 添加一个观察者:
viewmodelData
.getData()
.observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(String s) {
Log.v("TAG", "onChanged: " + s);
Gson gson = new Gson();
JsonObject root = gson.fromJson(s, JsonObject.class);
//parsing response...
}
});
这确保您的 LiveData 仅由单个观察者观察和处理。
点击按钮后,调用:
viewmodelData.loadData("param1", "param2", "param3", "param4", "param5");
我正在尝试掌握 Android 中的 MVVM 架构,并且正在为此开发一个示例应用程序。我暂时避免使用 Repository class,它避免了关注点分离,但我想先更好地理解 ViewModel 和 LiveData。我有一个片段,我在其中使用改造和 viewmodel 实例进行网络调用。然后使用相同的 viewmodel 对象进行相同的调用,但参数值不同。现在 onChanged 被触发,当我记录响应时(使用 log.d),我在其中得到了旧的响应。在几毫秒的延迟之后,HttpLoggingInterceptor 记录新的响应。我已经尝试了很多东西,但我无法弄清楚发生了什么。在搜索这个问题时,我发现了这个:
代码:
Api接口
public interface ApiInterface {
@GET("fetch")
Call<String> fetchData(@Query("param1") String param1,
@Query("param2") String param2,
@Query("param3") String param3,
@Query("param4") String param4,
@Query("param5") String param5);
ViewModelData
public class ViewModelData extends ViewModel {
private MutableLiveData<String> data = new MutableLiveData<>();
private final String TAG = getClass().getSimpleName();
public LiveData<String> getData(String param1, String param2, String param3, String param4,
String param5){
loadData(param1, param2, param3, param4, param5);
return data;
}
private void loadData(String param1, String param2, String param3, String param4,
String param5){
Retrofit retrofit = HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okHttpClientGet = new OkHttpClient.Builder()
.addInterceptor(logging)
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(ScalarsConverterFactory.create())
.client(okHttpClientGet)
.build();
ApiInterface apiInterface = retrofit.create(ApiInterface.class);
Call<String> call = apiInterface.fetchData(param1, param2, param3, param4, param5);
call.enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
if(response.isSuccessful()){
Log.v(TAG, "onResponse: " + response.body());
data.postValue(response.body());
}else{
try {
String errorBody = response.errorBody().string();
Log.e(TAG, "onResponse: " + errorBody);
data.postValue(errorBody);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void onFailure(Call<String> call, Throwable t) {
Log.e(TAG, "onFailure: " + t.getMessage());
}
});
}
FragmentTest(这是我定义的一个函数,点击一个按钮就会被调用)
viewmodelData.getData("param1", "param2", "param3",
"param4", "param5")
.observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(String s) {
Log.v("TAG", "onChanged: " + s);
Gson gson = new Gson();
JsonObject root = gson.fromJson(s, JsonObject.class);
//parsing response...
}
});
ViewModel 实例已创建为:
viewmodelData = new ViewModelProvider(this).get(ViewModelData.class);
我很感激任何帮助,因为我已经坚持了一段时间了。
您的流程正在为同一个 LiveData 添加多个观察者,这可能会导致您看到的问题。
在每次单击按钮时,您都会(再次)观察 getData() 返回的 LiveData 对象。
将您的 getData 方法更改为:
public LiveData<String> getData() {
return data;
}
并使您的 loadData 方法 public:
public void loadData(String param1, String param2, String param3, String param4, String param5) {
...
}
在您片段的 onCreateView() 中为您的 LiveData 添加一个观察者:
viewmodelData
.getData()
.observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(String s) {
Log.v("TAG", "onChanged: " + s);
Gson gson = new Gson();
JsonObject root = gson.fromJson(s, JsonObject.class);
//parsing response...
}
});
这确保您的 LiveData 仅由单个观察者观察和处理。
点击按钮后,调用:
viewmodelData.loadData("param1", "param2", "param3", "param4", "param5");