И 1), и 2) в конце концов делают одно и то же, но 2) всегда безопаснее.
Когда вы звоните dismiss()
, DialogFragment
отклоняется, а DialogFragment
остановлен (он получает обратный вызов на onStop()
). Это вызывает прослушиватель в DialogFragmentNavigator
, который затем обновляет состояние NavController
, вызывая popBackStack()
.
dismiss()
, однако это асинхронная операция (как видно из исходный код DialogFragment
- вы заметите, что он не использует commitNow()
, et c). Поэтому, если бы вы проверили, по какому пункту назначения вы находитесь из NavController.getCurrentDestination()
, вы бы увидели, что вы все еще находитесь в пункте назначения в диалоговом окне, несмотря на то, что вызвали увольнение.
navigateUp()
, с другой рука, идет прямо к NavController. Поскольку в вашем заднем стеке есть другой пункт назначения (тот, что находится под DialogFragment
), исходный код NavController
показывает, что navigateUp()
просто вызывает popBackStack()
- та же операция, что была dismiss()
в конечном итоге запуск.
Однако, когда NavController
управляет операцией, NavController
обновляет свое состояние синхронно. Это означает, что сразу после того, как вы позвоните navigateUp()
, он обновит свое getCurrentDestination()
и внутреннее состояние в дополнение к вызову через DialogFragmentNavigator
popBackStack()
, то есть то, что вызывает до dismiss()
(удаление упомянутого выше наблюдателя для предотвращения двойных увольнений).
Поэтому вызов navigateUp()
всегда является более безопасным выбором, поскольку он гарантирует, что NavController
синхронно обновляется до правильного состояния, а не полагается на FragmentManager
асинхронная синхронизация (что может означать, что в течение этого периода времени из-за мультитача получаются дополнительные события щелчка и т. Д.).
вызов navigate()
с действием, которое имеет app:destination
на нем будет перемещаться к новому экземпляру пункта назначения, который не подходит для возврата к вашему предыдущему экземпляру.