Mvvm 观察LiveData时为什么不调用onChanged()

Mvvm 观察LiveData时为什么不调用onChanged(),mvvm,retrofit,viewmodel,android-architecture-components,Mvvm,Retrofit,Viewmodel,Android Architecture Components,此问题是此问题的后续问题: 该帖子回复中强调的错误1和2已经修复。对于错误3,我还没有将API调用移动到存储库中,但是一旦代码开始正常工作,我就会这样做 因此,我尝试使用改型进行API调用,将MVVM与LiveData和ViewModel结合使用。API调用(当前位于ViewModel中)工作正常,但活动中的观察者未检测到更改 我已将ViewModel observer设置为: public class PopularGamesActivity extends AppCompatActivity

此问题是此问题的后续问题:

该帖子回复中强调的错误1和2已经修复。对于错误3,我还没有将API调用移动到存储库中,但是一旦代码开始正常工作,我就会这样做

因此,我尝试使用改型进行API调用,将MVVM与LiveData和ViewModel结合使用。API调用(当前位于ViewModel中)工作正常,但活动中的观察者未检测到更改

我已将ViewModel observer设置为:

public class PopularGamesActivity extends AppCompatActivity {


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;

@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);
        }
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;


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

}

public LiveData<List<Game>> getGameList() {
    final MutableLiveData<List<Game>> gameList = new MutableLiveData<>();

    // 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<List<Game>> call = client.getGame(FIELDS,
            ORDER,
            LIMIT);

    call.enqueue(new Callback<List<Game>>() {
        @Override
        public void onResponse(Call<List<Game>> call, Response<List<Game>> response) {
            Timber.d("api call sucesss");
            if (response.body() != null) {
                Timber.d("First game: " + response.body().get(0).getName());

                gameList.setValue(response.body());
            }
        }

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

    return gameList;
}
公共类PopularGamesActivity扩展了AppCompativity{
私有静态最终字符串igdbBaseUrl=”https://api-endpoint.igdb.com/";
私有静态最终字符串字段=“id、名称、类型、封面、流行度”;
私有静态最终字符串顺序=“流行度:desc”;
专用静态最终整数限值=30;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity\u popular\u games);
PopularGamesViewModel popViewModel=ViewModelProviders.of(this.get)(PopularGamesViewModel.class);
popViewModel.getGameList().observe(这是一个新的观察者(){
@凌驾
更改后的公共void(@Nullable List gameList){
String firstName=gameList.get(0.getName();
木材d(名字);
}
我的ViewModel代码如下:

public class PopularGamesActivity extends AppCompatActivity {


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;

@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);
        }
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;


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

}

public LiveData<List<Game>> getGameList() {
    final MutableLiveData<List<Game>> gameList = new MutableLiveData<>();

    // 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<List<Game>> call = client.getGame(FIELDS,
            ORDER,
            LIMIT);

    call.enqueue(new Callback<List<Game>>() {
        @Override
        public void onResponse(Call<List<Game>> call, Response<List<Game>> response) {
            Timber.d("api call sucesss");
            if (response.body() != null) {
                Timber.d("First game: " + response.body().get(0).getName());

                gameList.setValue(response.body());
            }
        }

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

    return gameList;
}
public类PopularGamesViewModel扩展了AndroidViewModel{
私有静态最终字符串igdbBaseUrl=”https://api-endpoint.igdb.com/";
私有静态最终字符串字段=“id、名称、类型、封面、流行度”;
私有静态最终字符串顺序=“流行度:desc”;
专用静态最终整数限值=30;
公共PopularGamesViewModel(@NonNull应用程序){
超级(应用);
}
公共LiveData getGameList(){
最终MutableLiveData游戏列表=新的MutableLiveData();
//创建改装生成器
reformation.Builder=新的reformation.Builder()
.baseUrl(igdbBaseUrl)
.addConverterFactory(GsonConverterFactory.create());
//建筑改造
改装改装=builder.build();
//创建改装客户端
RefundationClient=Refundation.create(RefundationClient.class);
Call Call=client.getGame(字段,
命令,
限制);
call.enqueue(新回调(){
@凌驾
公共void onResponse(调用、响应){
Timber.d(“api调用成功”);
if(response.body()!=null){
d(“第一个游戏:+response.body().get(0.getName());
gameList.setValue(response.body());
}
}
@凌驾
失败时公共无效(调用调用,可丢弃的t){
Timber.d(“api调用失败”);
}
});
返回游戏列表;
}
}


当我运行代码时,ViewModel类中的onResponse将从API调用中输出正确的响应,因此调用工作正常在PopularGameActivity类中,将永远不会被调用。有人能解释一下我做错了什么吗?谢谢!

好的,所以这是一个奇怪的android studio错误。我最初在真正的nexus 4设备上运行代码,而onChange从未被调用。但是,在模拟设备上运行后,它开始工作马上。现在,它也在我真正的设备上工作

我不知道背后的实际原因,但如果将来有人遇到onChange无法调用的问题,请尝试切换设备/模拟器


干杯。

我在一台设备上调试代码,遇到了同样的问题。 M'n的解决方案是简单地激活设备屏幕。
屏幕保护程序是问题所在。

因此,您可以在onChange中获得即时更新,而无需提出新的请求?因为这也是我要寻找的内容欢迎访问So!请阅读,然后