gpt4 book ai didi

java - Android MVVM 架构并通过 API 观察数据变化

转载 作者:行者123 更新时间:2023-12-01 19:32:36 25 4
gpt4 key购买 nike

我是 Android MVVM 架构的新手。我有一个本地运行的 API,其中包含数据(“交易”)。我只想向 API 发出请求并在文本字段中显示该数据。目前,首次加载 fragment 时数据不会显示,但如果我转到另一个 Activity ,然后返回到它加载的 fragment 。

这里有 3 个重要类别。

DashboardViewModel.java:

package com.example.android_client.ui.dashboard;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

import com.example.android_client.models.Deal;
import com.example.android_client.repository.Repository;

import java.util.List;

public class DashboardViewModel extends ViewModel {

private MutableLiveData<String> mText;
private Repository repository;
private MutableLiveData<List<Deal>> deals = null;

public void init() {
if(this.deals == null) {
this.repository = Repository.getInstance();
this.deals = this.repository.getDeals();
}
}

public DashboardViewModel() {
this.mText = new MutableLiveData<>();
}

public LiveData<List<Deal>> getDeals() {
return this.deals;
}
}

DashboardFragment.java:

package com.example.android_client.ui.dashboard;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;

import com.example.android_client.R;
import com.example.android_client.models.Deal;

import java.util.List;

public class DashboardFragment extends Fragment {

private DashboardViewModel dashboardViewModel;

public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_dashboard, container, false);
final TextView textView = root.findViewById(R.id.text_dashboard);
dashboardViewModel = ViewModelProviders.of(this).get(DashboardViewModel.class);
dashboardViewModel.init();
dashboardViewModel.getDeals().observe(this, new Observer<List<Deal>>() {
@Override
public void onChanged(List<Deal> deals) {
if (deals != null && !deals.isEmpty()) {
System.out.println(deals.get(0).toString());
textView.setText(deals.get(0).toString());
}
}
});
return root;
}
}

和Repository.java:

package com.example.android_client.repository;

import androidx.lifecycle.MutableLiveData;

import com.example.android_client.models.Deal;
import com.google.gson.Gson;

import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;

public class Repository {

private static Repository instance;
private ArrayList<Deal> dealsList = new ArrayList<>();
private final OkHttpClient client = new OkHttpClient();

public static Repository getInstance() {
if(instance == null) {
instance = new Repository();
}
return instance;
}

private Repository() {}

public MutableLiveData<List<Deal>> getDeals() {
setDeals();
MutableLiveData<List<Deal>> deals = new MutableLiveData<>();
deals.setValue(dealsList);
return deals;
}

private void setDeals() {
Request request = new Request.Builder()
.url("http://10.0.2.2:8000/api/deals?<params here>")
.build();

client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
e.printStackTrace();
}

@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
try (ResponseBody responseBody = response.body()) {
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
}
String jsonDeals = responseBody.string(); // can only call string() once or you'll get an IllegalStateException
Deal[] deals = new Gson().fromJson(jsonDeals, Deal[].class);
dealsList = new ArrayList<>(Arrays.asList(deals));
}
}
});

}
}

单步执行 Repository 类中的代码时,我可以看到加载 fragment 时调用了 setDeals(),并且回调中的请求已排队。第一次 getDeals() 返回时,它返回 0 个交易的列表(在 MutableLiveData 对象内)。

回调中的

onResponse 在 fragment 加载之前不会运行。调试时,我可以看到数据在对象中(所有 Gson 的东西都工作正常),但是 onChanged 不会再次被调用(它设置 TextView )。

我是否没有正确观察交易的变化?

最佳答案

由于每当调用 getDeals() 时都会创建一个新的实时数据实例,并且将 api 响应值通知给其他实时数据实例,因此您的代码无法正常工作。您必须将 api 响应值设置为 getDeals() 返回的 MutableLiveData 的同一实例

我并不是说这是最好的架构解决方案,但如果您创建一个可变的实时数据作为类属性,并在调用 getDeals() 时返回它。也许,它会起作用。

此外,一个好的做法是返回 LiveData 而不是 MutableLiveData,以不允许外部组件修改内部值。

请看一下下面的代码。

OBS:也许有一些语法错误,因为我还没有编译它

    import com.example.android_client.models.Deal;
import com.google.gson.Gson;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;

public class Repository {

private static Repository instance;
private ArrayList<Deal> dealsList = new ArrayList<>();
private final OkHttpClient client = new OkHttpClient();
private MutableLiveData<List<Deal>> _deals = new MutableLiveData<>();
private LiveData<List<Deal>> deals = _deals


public static Repository getInstance() {
if(instance == null) {
instance = new Repository();
}
return instance;
}

private Repository() {}

public LiveData<List<Deal>> getDeals() {
setDeals();
return deals;
}

private void setDeals() {
Request request = new Request.Builder()
.url("http://10.0.2.2:8000/api/deals?<params here>")
.build();

client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
e.printStackTrace();
}

@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
try (ResponseBody responseBody = response.body()) {
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
}
String jsonDeals = responseBody.string(); // can only call string() once or you'll get an IllegalStateException
Deal[] deals = new Gson().fromJson(jsonDeals, Deal[].class);
dealsList = new ArrayList<>(Arrays.asList(deals));
_deals.setValue(dealsList);

}
}
});

}

}
When

关于java - Android MVVM 架构并通过 API 观察数据变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59119461/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com