Android LiveData создает несколько наблюдателей во фрагменте - PullRequest
0 голосов
/ 21 сентября 2019

После поиска множества других вопросов SO и прочтения статей я все еще не могу понять, почему моя реализация не работает как другие примеры.

Я читал, что рекомендуется использовать getViewLifecycleOwner()при регистрации любых наблюдателей LiveData внутри фрагмента для правильной обработки жизненного цикла фрагмента.

Однако внутри моего фрагмента OnActivityCreated метод (который вызывается дважды, когда фрагмент отображается на экране), мне кажется,я получаю различные LifecycleOwner объекты от вызова к getViewLifecycleOwner(), что, как я полагаю, является причиной того, что я регистрирую нескольких наблюдателей в своем объекте LiveData.

Как мне предотвратить это / что я делаю неправильно?

Я добавил множество записей в код, как показано ниже:

MainActivity

   public class MainActivity extends AppCompatActivity {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.fragment, new LiveDataTestFragment())
                    .commit();

            Log.d("debugger2", "Activity: " + this.hashCode());
        }
    }

LiveDataTestFragment

public class LiveDataTestFragment extends Fragment {

    private LiveDataViewModel viewModel;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_live_data_test, container, false);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        viewModel = ViewModelProviders.of(getActivity()).get(LiveDataViewModel.class);

        Log.d("debugger2", "ViewModel: " + viewModel.hashCode());

        LiveData<String> liveData = viewModel.getLiveData();
        Log.d("debugger2", "LiveData: " + liveData.hashCode());

        LifecycleOwner lifecycleOwner = getViewLifecycleOwner();
        Log.d("debugger2", "LifeCycleOwner: " + lifecycleOwner.hashCode());

        liveData.observe(lifecycleOwner, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                Log.d("debugger2", "observer hash: " + this.hashCode());
            }
        });
    }
}

Logcat:

D: Activity: 242098714
D: ViewModel: 149122972
D: LiveData: 58736037
D: LifeCycleOwner: 50378106
D: ViewModel: 149122972
D: LiveData: 58736037
D: LifeCycleOwner: 245135826
D: observer hash: 204470220
D: observer hash: 226765595

Ответы [ 2 ]

0 голосов
/ 21 сентября 2019

Я понял проблему.Спасибо за ответы, независимо!

Я поставлю эту проблему здесь, хотя вряд ли кто-нибудь еще сделает то, что я сделал!

В моем файле activity_main.xml содержится

<fragment
    android:name="com.test.livedatatestapp.LiveDataTestFragment"
    android:id="@+id/fragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

который создавал экземпляр класса Fragment, который я затем немедленно заменил внутри MainActivity, заменив Fragment, отсюда и дубликаты ...

0 голосов
/ 21 сентября 2019
new Observer<String>() {
            @Override
            public void onChanged(String s) {
                Log.d("debugger2", "observer hash: " + this.hashCode());
            }
        }

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

private Observer<String> singleObserver = Observer<String>() {
                @Override
                public void onChanged(String s) {
                    Log.d("debugger2", "observer hash: " + this.hashCode());
                }
}

и используйте его как:

// your previous code
LiveData<String> liveData = viewModel.getLiveData();
liveData.observe(lifecycleOwner, singleObserver);
// rest of your code

Надеюсь, это сработает.

...