Запрос на топ х элементов в Джанго

Это октябрь 2017 года, и Google делает Android Support Library новой компонентой Lifecycle. Это дает некоторую новую идею для этого «Невозможно выполнить это действие после проблемы onSaveInstanceState».

Короче:

  • Используйте компонент жизненного цикла, чтобы определить, правильно ли это время для всплытия ваш фрагмент.

Более длинная версия с объяснением:

  • почему эта проблема возникает? Это потому, что вы пытаетесь использовать FragmentManager из своей активности (которая, как предполагается, держит ваш фрагмент, предположим?), Чтобы зафиксировать транзакцию для фрагмента. Обычно это будет выглядеть так, как будто вы пытаетесь выполнить некоторую транзакцию для следующего фрагмента, в то время как активность хоста уже вызывает метод savedInstanceState (пользователь может попасть в домашнюю кнопку, чтобы активность вызывала onStop(), в моем случае это Причина) Обычно эта проблема не должна происходить - мы всегда пытаемся загрузить фрагмент в действие в самом начале, как метод onCreate() - это идеальное место для этого. Но иногда это случается, особенно когда вы не можете решить, какой фрагмент вы загрузите для этой активности, или вы пытаетесь загрузить фрагмент из блока AsyncTask (или что-то займет немного времени). Время, прежде чем транзакция фрагмента действительно произойдет, но после метода onCreate() активности пользователь может сделать что угодно. Если пользователь нажимает кнопку «домой», которая запускает метод onSavedInstanceState() активности, произошел сбой can not perform this action. Если кто-то захочет увидеть глубже в этом вопросе, я предлагаю им взглянуть на этот блог post . Он выглядит глубоко внутри исходного кода и объясняет многое об этом. Кроме того, это указывает на то, что вы не должны использовать метод commitAllowingStateLoss() для обхода этого сбоя (верьте мне, что он не предлагает ничего хорошего для вашего кода)
  • Как это исправить? Должен ли я использовать метод commitAllowingStateLoss() для загрузки фрагмента? Нет, не стоит; Должен ли я переопределить метод onSaveInstanceState, игнорировать метод super внутри него? Нет, не стоит; Должен ли я использовать магическую активность isFinishing для проверки активности хоста в нужный момент для транзакции фрагмента? Да, это похоже на правильный путь.
  • Посмотрите, что может сделать компонент Lifecycle . В основном, Google делает некоторую реализацию внутри класса AppCompatActivity (и нескольких других базовых классов, которые вы должны использовать в своем проекте), что упрощает определение текущего состояния жизненного цикла. Оглянитесь на нашу проблему: почему эта проблема возникнет? Это потому, что мы делаем что-то не так. Поэтому мы стараемся не делать этого, и эта проблема исчезнет. Я немного код для своего проекта, вот что я использую LifeCycle. Я код в Котлин.
val hostActivity: AppCompatActivity? = null // the activity to host fragments. It's value should be properly initialized.

fun dispatchFragment(frag: Fragment) {
    hostActivity?.let {
       if(it.lifecyclecurrentState.isAtLeast(Lifecycle.State.RESUMED)){
           showFragment(frag)
       }
    }
}

private fun showFragment(frag: Fragment) {
    hostActivity?.let {
        Transaction.begin(it, R.id.frag_container)
                .show(frag)
                .commit()
    }

Как я показал выше. Я проверю состояние жизненного цикла активности хоста. С компонентом Lifecycle в библиотеке поддержки это может быть более конкретным. Код lifecyclecurrentState.isAtLeast(Lifecycle.State.RESUMED) означает, что если текущее состояние не менее onResume, не позднее этого? Это гарантирует, что мой метод не будет выполняться во время какого-либо другого состояния жизни (например, onStop).

  • Все ли сделано? Конечно нет. Код, который я показал, говорит о новом способе предотвращения сбоя приложения. Но если он перейдет к состоянию onStop, эта строка кода не будет делать ничего, и, таким образом, не покажет ничего на вашем экране. Когда пользователи возвращаются в приложение, они будут видеть пустой экран, это пустая активность хоста, которая не показывает никаких фрагментов. Это плохой опыт (да немного лучше, чем крушение). Поэтому я хочу, чтобы было что-то приятнее: приложение не будет разбиваться, если дело дойдет до состояния жизни позже onResume, метод транзакции - это состояние жизни; кроме того, действие будет пытаться продолжить завершение этого действия транзакции фрагмента после того, как пользователь вернется в наше приложение. Я добавляю что-то еще к этому методу:
class FragmentDispatcher(_host: FragmentActivity) : LifecycleObserver {
    private val hostActivity: FragmentActivity? = _host
    private val lifeCycle: Lifecycle? = _host.lifecycle
    private val profilePendingList = mutableListOf()

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun resume() {
        if (profilePendingList.isNotEmpty()) {
            showFragment(profilePendingList.last())
        }
    }

    fun dispatcherFragment(frag: BaseFragment) {
        if (lifeCycle?.currentState?.isAtLeast(Lifecycle.State.RESUMED) == true) {
            showFragment(frag)
        } else {
            profilePendingList.clear()
            profilePendingList.add(frag)
        }
    }

    private fun showFragment(frag: BaseFragment) {
        hostActivity?.let {
            Transaction.begin(it, R.id.frag_container)
                    .show(frag)
                    .commit()
        }
    }
}

Я поддерживаю список внутри этого класса dispatcher, чтобы сохранить этот фрагмент, не имеет шансов завершить действие транзакции. И когда пользователь возвращается с главного экрана и обнаружил, что все еще есть фрагмент, ожидающий запуска, он перейдет к методу resume() в аннотации @OnLifecycleEvent(Lifecycle.Event.ON_RESUME). Теперь я думаю, что он должен работать так, как я ожидал.

30
задан brsbilgic 22 June 2011 в 08:23
поделиться