Android-刷新片段时不会取消订阅LiveData

时间:2018-12-14 15:26:23

标签: java android android-fragments android-livedata

所以我有一个奇怪的情况。我实现了一个具有单个活动和两个片段的应用程序。两个片段都有一个过滤器选项,可以在其中选择一个类别。

基于类别,当前片段将使用新类别刷新和获取数据。

我正在使用ViewModel来获取数据,并使用LiveData来观察更改。

我的Fragment类和我的ViewModel

When a button is clicked in the Activity class, this method is called:
public static void replaceFragment(Activity activity,
                                       int navId,
                                       int selectedPosition) {
        Bundle bundle = new Bundle();
        bundle.putInt(INTENT_CATEGORY, selectedPosition);
        Navigation.findNavController(activity, R.id.fragment_nav_host)
                .navigate(navId, bundle, new NavOptions.Builder()
                        .setEnterAnim(R.anim.flip_right_in)
                        .setExitAnim(R.anim.flip_right_out)
                        .setPopEnterAnim(R.anim.flip_left_in)
                        .setPopExitAnim(R.anim.flip_left_out)
                        .build());
    }

我正在使用导航组件。所以奇怪的问题是,当我刷新片段时,LiveData被多次调用。我了解到,重新创建或刷新片段时,viewModel实例仍然相同。但不确定为什么会发生此问题。

如果有人可以帮助解决此问题,将不胜感激。

可以找到整个应用代码here

更新: 因此,如果我从以下位置更改InitializeViewModel()方法:

private void initialiseViewModel() {
    moviesListViewModel = ViewModelProviders.of(this, viewModelFactory).get(MovieListViewModel.class);
    moviesListViewModel.fetchMovies(MENU_MOVIE_ITEM.get(getArguments() == null ? 0: getArguments().getInt(INTENT_CATEGORY)));
    moviesListViewModel.getMoviesLiveData().observe(this, resource -> {
        if(resource.isLoading()) {
            displayLoader();

        } else if(resource.data != null && !resource.data.isEmpty()) {
            handleSuccessResponse(resource.data);

        } else handleErrorResponse();
    });
}

TO

    private void initialiseViewModel() {

        AppDatabase appDatabase = Room.databaseBuilder(getContext(),
                AppDatabase.class, "Entertainment.db")
                .allowMainThreadQueries().build();

        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);

        OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
        httpClient.addInterceptor(logging);
        httpClient.addNetworkInterceptor(new RequestInterceptor());
        httpClient.connectTimeout(30, TimeUnit.SECONDS);
        httpClient.readTimeout(30, TimeUnit.SECONDS);

        MovieApiService movieApiService =
                new Retrofit.Builder()
                        .addConverterFactory(GsonConverterFactory.create(new GsonBuilder().create()))
                        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                        .baseUrl(BASE_URL)
                        .client(httpClient.build())
                        .build().create(MovieApiService.class);

//        moviesListViewModel = ViewModelProviders.of(this, viewModelFactory).get(MovieListViewModel.class);
        moviesListViewModel = new MovieListViewModel(appDatabase.movieDao(), movieApiService);
        moviesListViewModel.fetchMovies(MENU_MOVIE_ITEM.get(getArguments() == null ? 0: getArguments().getInt(INTENT_CATEGORY)));
        moviesListViewModel.getMoviesLiveData().observe(this, resource -> {
            if(resource.isLoading()) {
                displayLoader();

            } else if(resource.data != null && !resource.data.isEmpty()) {
                handleSuccessResponse(resource.data);

            } else handleErrorResponse();
        });
    }

然后问题似乎消失了:(。关于为什么的任何指针?

0 个答案:

没有答案