LiveData在从堆栈弹出后将其Fragment中的观察者停用

时间:2018-10-03 12:48:19

标签: android viewmodel android-lifecycle android-architecture-components android-livedata

每次用户来到HomeFragment时,我需要执行一项任务。不管是新创建的还是用户回到此Fragment

在新创建时可以正常工作,但是从后退堆栈返回时,不会调用观察器。我使用调试器发现的是LiveData有观察者,hasActiveObservers()返回false 。我尝试从不同的生命周期回调中操作和观察/删除Observer,但均未成功。在Google中也找不到清晰的解释。

这是我的HomeFragment.java

public class HomeFragment extends BaseFragment {
    //.......
    private ImportViewModel viewModel;

    private Observer<State> observer = state -> {
        //update UI depending on a state
    };

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        viewModel = ViewModelProviders.of(this, viewModelFactory).get(ImportViewModel.class);
        observeViewModel();
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_home, container, false);

        //execute here since onCreate() is not called when coming from backstack
        viewModel.importFile();

        return v;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        viewModel.liveDataState.removeObserver(observer);
    }

    private void observeViewModel() {
        viewModel.liveDataState.observe(this, observer);
    }

    //.......
}

还有ImportViewModel.java

public class ImportViewModel extends ViewModel {

    //......
    public MutableLiveData<State> liveDataState = new MutableLiveData<>();
    //......
    public void importFile(){
        disposables.add(repository.importFile()
                .subscribeOn(subscribeOnScheduler)
                .observeOn(observeOnScheduler)
                .subscribe(this::onNext, this::onError, this::onComplete));
    }

     private void onNext(SomeResponse resp){
        liveDataState.setValue(new State(resp));
    }

    private void onError(Throwable t){
        liveDataState.setValue(new ErrorState(t.getMessage()));
    }

    private void onComplete(){
        liveDataState.setValue(new CompleteState());
    }
}

为什么观察者不活动?

1 个答案:

答案 0 :(得分:0)

我有类似的问题。我的情况是我要从家庭片段转到另一个片段,并且通过将片段视图设置为全局来维护片段的状态,在create view方法中,我首先检查视图是否不为null,然后不进行任何设置。到那时为止一切都很好。

我的问题是,当我从那个片段回来时,实时数据的变化没有被观察到。

我设法用onResume方法做到这一点。

private fun setupObserver() {
        val observer: Observer<MutableList<Post>> = Observer {
            //            textView.text = homeViewModel.text.value?.get(0)?.name ?: "Loading"
            Log.d(
                AppConstants.GLOBAL_LOGTAG,
                "observed with current page = ${homeViewModel.getMetaData().currentPage}"
            )
            //logic to show progress

            if (!isObservedAtLeastOneTime) {
                showProgress()
            }
            if (homeViewModel.getMetaData().currentPage == 1) {
                list.clear()
                list.addAll(homeViewModel.mutableLiveData.value!!)
                recentPostsAdapter.notifyDataSetChanged()
            } else {
                list.clear()
                list.addAll(homeViewModel.mutableLiveData.value!!)
                recentPostsAdapter.notifyDataSetChanged()
            }
            if (isObservedAtLeastOneTime) {
                hideProgressAndShowContent()
            }
            isObservedAtLeastOneTime = true
            isLoading = false
            swipeRefreshLayout.isRefreshing = false
        }
        if (!homeViewModel.mutableLiveData.hasActiveObservers()) {
            homeViewModel.mutableLiveData.observe(viewLifecycleOwner, observer)
        }
    }

然后使用恢复方法。

override fun onResume() {
        super.onResume()
        if(!homeViewModel.mutableLiveData.hasActiveObservers()){
            setupObserver()
        }
    }