gpt4 book ai didi

android - 如何使用 ViewModel 和 LiveData 进行改造 API 调用

转载 作者:行者123 更新时间:2023-12-02 02:48:43 26 4
gpt4 key购买 nike

这是我第一次尝试实现 MVVM 架构,我对调用 API 的正确方法有点困惑。

目前,我只是尝试从 IGDB API 进行简单的查询,并输出日志中第一项的名称。

我的 Activity 设置如下:

public class PopularGamesActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_popular_games);


PopularGamesViewModel popViewModel = ViewModelProviders.of(this).get(PopularGamesViewModel.class);
popViewModel.getGameList().observe(this, new Observer<List<Game>>() {
@Override
public void onChanged(@Nullable List<Game> gameList) {
String firstName = gameList.get(0).getName();
Timber.d(firstName);
}
});
}
}

我的 View 模型设置如下:

public class PopularGamesViewModel extends AndroidViewModel {

private static final String igdbBaseUrl = "https://api-endpoint.igdb.com/";
private static final String FIELDS = "id,name,genres,cover,popularity";
private static final String ORDER = "popularity:desc";
private static final int LIMIT = 30;

private LiveData<List<Game>> mGameList;

public PopularGamesViewModel(@NonNull Application application) {
super(application);


// Create the retrofit builder
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(igdbBaseUrl)
.addConverterFactory(GsonConverterFactory.create());

// Build retrofit
Retrofit retrofit = builder.build();

// Create the retrofit client
RetrofitClient client = retrofit.create(RetrofitClient.class);
Call<LiveData<List<Game>>> call = client.getGame(FIELDS,
ORDER,
LIMIT);

call.enqueue(new Callback<LiveData<List<Game>>>() {
@Override
public void onResponse(Call<LiveData<List<Game>>> call, Response<LiveData<List<Game>>> response) {
if (response.body() != null) {
Timber.d("Call response body not null");
mGameList = response.body();

} else {
Timber.d("Call response body is null");
}
}

@Override
public void onFailure(Call<LiveData<List<Game>>> call, Throwable t) {
Timber.d("Retrofit call failed");
}
});

}

public LiveData<List<Game>> getGameList() {
return mGameList;
}

现在的问题是,因为这是一个 API 调用,所以 mGameList 的初始值将为 null,直到 call.enqueue 返回一个值。这将导致空指针异常

popViewModel.getGameList().observe(this, new Observer<List<Game>>() {
  1. 那么处理 LiveData 观察的正确方法是什么?当 API 调用正在进行时?
  2. 我是否执行了 Retrofit API 调用 在正确的地方?

最佳答案

您的代码中有 3 个问题。

  1. 您必须创建一个 MutableLiveData 对象,因为在 API 调用之前您有一个空响应,然后您的 LiveData 对象将通过 IGDB 响应以某种方式填充。
private MutableLiveData<List<Game>> mGameList = new MutableLiveData();
//...
public LiveData<List<Game>> getGameList() {
return mGameList;
}
  • 另一个错误是更改mGameList的引用而不是设置其值,因此尝试更改:
  • Timber.d("Call response body not null");
    mGameList = response.body();

    mGameList.setValue(response.body());
  • ViewModel类中调用retrofit可以避免关注点分离。最好创建一个存储库模块并通过接口(interface)获取响应。阅读此article了解详情。
  • Repository modules are responsible for handling data operations. They provide a clean API to the rest of the app. They know where to get the data from and what API calls to make when data is updated. You can consider them as mediators between different data sources (persistent model, web service, cache, etc.).

    关于android - 如何使用 ViewModel 和 LiveData 进行改造 API 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51780696/

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