onBackPressedDispatcher.onBackPressed() против backPressedCallback.handleOnBackPressed()

Так как старыйActivity.onBackPressed()становится устаревшим, начиная с Android 33, как лучше назвать это программно?

Пример:

      override fun onOptionsItemSelected(item: MenuItem): Boolean {

        when (item.itemId) {

            // Handle default back arrow click
            android.R.id.home -> {
                onBackPressed()
            }
 ...

Мы могли бы создать и добавить к подобному.

      onBackPressedDispatcher.addCallback(
            this, // Lifecycle owner
            backPressedCallback
        )

private val backPressedCallback = object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            if (viewPager.currentItem != 0)
                viewPager.setCurrentItem(0, true)
            else
                finish()
        }
    }

Затем заменить старыйonBackPressedс

      // Handle default back arrow click
            android.R.id.home -> {
                backPressedCallback.handleOnBackPressed()
            }

Но я увидел этот общедоступный метод и подумал, могу ли я использовать его вместо этого.

      onBackPressedDispatcher.onBackPressed()

Повторяет ли этот метод каждыйOnBackPressedCallbackчто было добавлено вonBackPressedDispatcher?

1 ответ

Так что в основномonBackPressedDispatcher.onBackPressed()такой же какActivity.onBackPressed()и вы можете использовать его таким же образом, если вам не нужна точная навигация. Откуда я это знаю? - ну, вы можете увидеть исходный кодComponentActivity(в основном это родитель обычного действия, которое вы используете), и оно выглядит так:

          @Override
    @MainThread
    public void onBackPressed() {
        mOnBackPressedDispatcher.onBackPressed();
    }

Что касается его вызова через очередь обратных вызовов - вы также правы, но он не перебирает его, а просто вызывает самый последний - по одному (за нажатие или заonBackPressed()триггер вызова), в документации указано:

public void onBackPressed()

Инициировать вызов текущих добавленных обратных вызовов в обратном порядке, в котором они были добавлены. Только если последний добавленный обратный вызов неenabledбудет вызываться любой ранее добавленный обратный вызов.

Если hasEnabledCallbacks имеет значение false при вызове этого метода, резервный Runnable, установленныйthe constructorбудет запущен.

Таким образом, ваша стратегия здесь может быть такой: если вам нужно выполнить какие-то конкретные действия перед обратной навигацией, вы добавляете их вhandleOnBackPressedобратного вызова. Если не требуется особого поведения - вы можете просто позвонитьmOnBackPressedDispatcher.onBackPressed()- он все равно будет вызывать последний добавленный (если он есть конечно) метод обратного вызова, но если он пустой - обратный вызов будет работать нормально.

Вы должны иметь в виду, однако, что есть два переопределенияaddCallbackметоды:

      addCallback(@NonNull OnBackPressedCallback onBackPressedCallback)

и

      public void addCallback(
    @NonNull LifecycleOwner owner,
    @NonNull OnBackPressedCallback onBackPressedCallback
)

В первом случае вы должны сами обрабатывать очередь обратного вызова, вызываяremoveпри обратном вызове, когда вам нужно, чтобы он больше не выполнялся. В последнем -LifecycleOwnerизменение состояния должно обрабатывать все необходимые вещи для вас.

Больше информации здесь и здесь .