LiveData 观察()未调用

Posted

技术标签:

【中文标题】LiveData 观察()未调用【英文标题】:LiveData observe() not called 【发布时间】:2019-02-04 09:00:17 【问题描述】:

我的观察者回调没有被调用,你能指出我做错了什么吗?我的应用程序非常简单,因为我只是在测试这个架构

MainActivity 代码

viewModel = ViewModelProviders.of(this).get(UpcomingMoviesViewModel.class);
viewModel.getUpcomingMovies().observe(this, upcomingMovies -> 
        // NOT CALLED !!!
        for(UpcomingMovies movie : upcomingMovies) 
            Log.d("Upcoming", "Movie - " + movie.movie.title);
        
    );

ViewModel 代码

private LiveData<List<UpcomingMovies>> mUpcomingMovies;
private MovieRepository movieRepository;

public UpcomingMoviesViewModel(@NonNull Application application ) 
    super(application);
    movieRepository = MovieRepository.getsInstance(application); 


public LiveData<List<UpcomingMovies>> getUpcomingMovies() 
    mUpcomingMovies = movieRepository.getUpcomingMovies();
    return mUpcomingMovies;

还有我的存储库方法

public LiveData<List<UpcomingMovies>> getUpcomingMovies()
    if(movieDao.loadUpcomingMovies().getValue() == null) 
        webService.getUpcomingMovies(api_key).
                enqueue(new Callback<MovieResults>() 

                    @Override
                    public void onResponse(Call<MovieResults> call, Response<MovieResults> response) 
                        MovieResults results = response.body();
                        if(results == null) return;
                        new insertAsyncTask(movieDao).execute(results.movies.toArray(new Movie[results.movies.size()]));
                    

                    @Override
                    public void onFailure(Call<MovieResults> call, Throwable t) 
                        Log.d("Retrofit error", t.getMessage());
                    
                );
    
    return movieDao.loadUpcomingMovies();


private static class insertAsyncTask extends AsyncTask<Movie, Void, Void> 

    private final MovieDao mAsyncTask;

    insertAsyncTask(MovieDao dao)
        mAsyncTask = dao;
    

    @Override
    protected Void doInBackground(Movie... movies) 
        long [] results = mAsyncTask.insertMovies(Arrays.asList(movies));
        long [] results2 = mAsyncTask.insertUpcomingMovies(Arrays.asList(movies));
        return null;
    

resultsresults2 都返回 20 个数字,我认为这是因为我收到了 20 部电影。 我在这里做错了什么?谢谢你的时间

【问题讨论】:

【参考方案1】:

将 LifeCyclebserver 实现到 viewModel 并将其添加到您的活动中:

getLifecycle().addObserver(viewModel);

【讨论】:

postValue 是来自 MutableLiveData 而不是 LiveData 的方法 是的,将您的 mUpcomingMovies 初始化为 MutableLiveData。我忘了添加那个代码。您还确定数据会持续到 viewModel 吗? 抛出异常说 mUpcomingMovies 为空 像这样初始化: private MutableLiveData> mUpcomingMovies = new MutableLiveData>() 我正在使用这条线 mUpcomingMovies.postValue(movieRepository.getUpcomingMovies().getValue()); 。它仍然没有被调用【参考方案2】:

请记住,您的 viewModel 需要有一个不带参数的构造函数

【讨论】:

不确定这是否能回答问题。 OP 没有收到 NullReferenceException,因此他们的 ViewModel 似乎已正确实例化。 (我猜 OP 从 androidViewModel 派生了他们的 ViewModel)。【参考方案3】:

对于源片段和目标片段中的Java,调用;

viewModel = new ViewModelProvider(getActivity()).get(YourViewModel.class);

没有

viewModel = new ViewModelProvider(this).get(YourViewModel.class);

getActivity 而不是this 允许您引用相同的活动

【讨论】:

以上是关于LiveData 观察()未调用的主要内容,如果未能解决你的问题,请参考以下文章

Android Room LiveData观察器未更新

LiveData 未通知我的服务(LifecyclerOwner 实施)观察者

为啥观察 LiveData 时不调用 onChanged()

在 xml 中设置/观察 livedata 的正确方法是啥?调用观察者方法失败

LiveData详解

Android LiveData防止在观察时接收到最后一个值