Вызвано java.lang.IllegalStateException: Невозможно создать ViewModelProvider для отдельного фрагмента. - PullRequest
0 голосов
/ 09 мая 2018

Мне нужна помощь, чтобы решить следующую аварию. Я обновляю свой список при перезагрузке в Activity, вызывая fragment в viewpager, чтобы обновить его список. Ниже приведена трассировка стека:

Caused by java.lang.IllegalStateException: Can't create ViewModelProvider for detached fragment
       at android.arch.lifecycle.ViewModelProviders.checkActivity(ViewModelProviders.java:51)
       at android.arch.lifecycle.ViewModelProviders.of(ViewModelProviders.java:105)
       at com.ui.fragments.mainpagerfragments.ConversationListFragment.searchConversation(ConversationListFragment.java:383)
       at com.ui.activities.HomeActivity.onRestart(HomeActivity.java:288)
       at android.app.Instrumentation.callActivityOnRestart(Instrumentation.java:1256)
       at android.app.Activity.performRestart(Activity.java:6365)
       at android.app.Activity.performResume(Activity.java:6376)
       at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3299)
       at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3345)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1532)
       at android.os.Handler.dispatchMessage(Handler.java:111)
       at android.os.Looper.loop(Looper.java:207)
       at android.app.ActivityThread.main(ActivityThread.java:5728)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)

звонок с активности наRestart:

((MyListFragment) adapter.getFragmentAtPosition(0)).search("");

метод во фрагменте:

public void search(String query) {

        query = "%" + query + "%";
        if (myListViewModel == null) {
            myListViewModel = ViewModelProviders.of(this, viewModelFactory).get(MyListViewModel.class);
        }
        if (myListViewModel.mList != null && myListViewModel.mList.hasActiveObservers()) {
            myListViewModel.mList.removeObservers(this);
        }
        myListViewModel.getFilteredList(query).observe(this, mainObserver);
    }

Ответы [ 2 ]

0 голосов
/ 31 июля 2019
@Override
public void onAttach(Context context) {
    super.onAttach(context);
    myListViewModel = ViewModelProviders.of(this, viewModelFactory).get(MyListViewModel.class);
}
0 голосов
/ 09 мая 2018

Если вы используете видовой пейджер, убедитесь, что соответствующий фрагмент действительно привязан к его активности (это то, что ошибка пытается сообщить вам). Может случиться, что фрагмент не виден, поэтому он не прикреплен (в зависимости от того, как был настроен пейджер представления).

быстрое и грязное исправление:

public void search(String query) {

    if(!isAdded()) return; //<---- returns if the fragment is not attached

    query = "%" + query + "%";
    if (myListViewModel == null) {
        myListViewModel = ViewModelProviders.of(this, viewModelFactory).get(MyListViewModel.class);
    }
    if (myListViewModel.mList != null && myListViewModel.mList.hasActiveObservers()) {
        myListViewModel.mList.removeObservers(this);
    }
    myListViewModel.getFilteredList(query).observe(this, mainObserver);
}

Однако вам следует повторно исследовать свою архитектуру, поскольку эти проверки часто подразумевают некоторые другие запахи кода. При работе с новыми шаблонами архитектуры Android эта проверка не требуется, так как шаблон жизненного цикла обрабатывает все это для вас: https://developer.android.com/topic/libraries/architecture/lifecycle

Таким образом, в принципе, вы не должны напрямую вызывать какую-либо функцию фрагмента, вместо этого вызывать соответствующую бизнес-логику, которая уведомляет фрагмент об обновлении его представлений.

...