使用Retrofit 2检索的对象无法在MutableLiveData中设置值

时间:2018-05-13 08:15:37

标签: android retrofit2 android-livedata

我正在尝试遵循Android架构指南来制作此应用。我有一个MovieRepository负责获取JSON(数据层),我有一个ViewModel,它将数据提供给我的MainActivity中的UI。我正在使用改造2来完成我的网络任务。

MovieRespository代码:

public class MovieRepository {

    private static final String TAG = MovieRepository.class.getSimpleName();

    public LiveData<ReturnMovie> search(String term) {
        final MutableLiveData<ReturnMovie> data = new MutableLiveData<>();

        MovieService service = ServiceGenerator.createService(MovieService.class);
        Call<ReturnMovie> call = service.requestMovie(term, MovieAPIUtils.KEY);

        call.enqueue(new Callback<ReturnMovie>() {
            @Override
            public void onResponse(Call<ReturnMovie> call, Response<ReturnMovie> response) {
                ReturnMovie movie = response.body();
                data.setValue(movie);
                Log.d(TAG, data.getValue().getPage().toString());
            }
            @Override
            public void onFailure(Call<ReturnMovie> call, Throwable t) {
                Log.d(TAG, t.toString());
            }
        });
        return data;
    }
}

MovieService:

public interface MovieService {

    @GET(MovieAPIUtils.Path.MOVIE_PATH + "/{param}")
    Call<ReturnMovie> requestMovie (@Path("param") String endpoints,
                                    @Query(MovieAPIUtils.Query.API_QUERY) String key);

}

视图模型:

public class MainActivityMovieViewModel extends ViewModel {

    private static final String TAG = MainActivityMovieViewModel.class.getSimpleName();

    private LiveData<ReturnMovie> movie;
    private MovieRepository repo = new MovieRepository();

    public LiveData<ReturnMovie> getMovie(String searchTerm) {

        if (movie == null) {
            movie = repo.search(searchTerm);
        }

        return movie;
    }
}

MainActivity:

public class MainActivity extends AppCompatActivity implements MovieAdapter.MovieOnClickListener {

    private RecyclerView mRecyclerView;
    private MovieAdapter mMovieAdapter;
    private MainActivityMovieViewModel viewModel;
    private static final String TAG = MainActivity.class.getSimpleName();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        viewModel = ViewModelProviders.of(this).get(MainActivityMovieViewModel.class);
        initRecyclerViewWithMovies();

        ReturnMovie movie = viewModel.getMovie(MovieAPIUtils.Endpoints.POPULAR_ENDPOINT).getValue();

// other code....

    }

onResponse(new Callback<ReturnMovie>)我能够检索电影对象,我通过记录其中一个属性值来证明它,因此有一个有效的ReturnMovie对象。但是,在我的MainActivity中,方法ReturnMovie movie = viewModel.getMovie(MovieAPIUtils.Endpoints.POPULAR_ENDPOINT).getValue();给了我一个空值。我检查到处都是看不出问题所在。

其余代码在我的Github上: https://github.com/brendoncheung/PopularMovie/tree/mvvm_approach

1 个答案:

答案 0 :(得分:1)

您使用Android体系结构组件,它在实时数据中使用可观察模式。如果您刚刚获得了liveata的当前值,那么您不确定它是否已被处理。 代替 ReturnMovie movie = viewModel.getMovie(MovieAPIUtils.Endpoints.POPULAR_ENDPOINT).getValue();我认为你应该使用

viewModel.getMovie(MovieAPIUtils.Endpoints.POPULAR_ENDPOINT).observe(this, new Observer<ReturnMovie>() {
        @Override
        public void onChanged(@Nullable ReturnMovie movie) {
          //do stuff with the movie
          doSomething(movie);
        }
    });    

您不必管理取消订阅,因为架构组件管理活动本身的取消订阅

看看:https://developer.android.com/topic/libraries/architecture/livedata