It depends on which Lifecycle object are you going to pass to your Observer.
Let's say you subscribe your Observer in Fragment's onCreate method. This solve the problems with observe called twice, but if the user press back button the Fragment A's onCreate won't be called so no Observer subscribed. Or even in some cases your observe method can be called while your Fragment is now active and leads to crash.
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
viewModel.liveData.observe(this, Observer { myData -> {} });
}
The second option you have is to subscribe in onCreateView() or onViewCreated(). The problem with these two options is that it will get called everytime the Fragment A gets recreated and at the end you will end up with more than one observers.
public void onViewCreated(View view, Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);
viewModel.liveData.observe(this, Observer { myData -> {} });
}
So how we can solve those issues? The answer is simple: use viewLifecycleOwner.
public void onViewCreated(View view, Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);
viewModel.liveData.observe(viewLifecycleOwner, Observer { myData -> {} });
}
Because in this way you observe your LiveData bound to Fragment view's lifecycle.
So it is safe to observe LiveData in onCreateView or onViewCreated and in onActivityCreated since it'se called after onCreateView by documentation: Link (but deprecated in API Level 28 and not encouraged to be used anymore).
P.S. A really helpful talk on this problem in Google IO 2018: Youtube Link