Разница между созданием нового фрагмента и получением существующего от менеджера при ротации

Кажется, установил ли я для свойства keepInstance значение true или нет, когда я поворачиваю устройство, я получаю существующий фрагмент. Разница в том, что если я установлю значение true, я получу «test = yes!», В противном случае - «test = no!». после поворота устройства после нажатия кнопки тестирования для смены test. То есть переменная-член сохраняется, если я сохраню экземпляр.

Но, как я уже сказал, даже если я не сохраню его, я все равно получаю от менеджера существующий фрагмент (всегда получаю «Повторное использование существующего» при ротации). В том случае, если все переменные-члены потеряны и представления фрагмента воссоздаются, что сохраняется? В чем смысл получения существующего экземпляра фрагмента?

В действии onCreate,

    var frag = supportFragmentManager.findFragmentById(R.id.frame)

    if (frag == null)
    {
        frag = Fragment1.newInstance("", "");
    }
    else
    {
        Log.d("sss", "Reusing exsiting");
    }

    val transaction = supportFragmentManager.beginTransaction()
    transaction.replace(R.id.frame, frag)
    transaction.commit()

Во фрагменте

var test = "no!";

override fun onViewCreated(view: View, savedInstanceState: Bundle?)
{
    super.onViewCreated(view, savedInstanceState)
    Log.d("sss", "test = " + test);
    testButton.setOnClickListener {
        test = "yes!";
    }
}
... Я получаю существующий фрагмент. - если вы не используете setRetainInstance (), этот фрагмент был создан FragmentManager после ротации для репликации предыдущего стека фрагментов, созданных вашим приложением. В onCreate () нет смысла повторно добавлять фрагмент, если вы найдете его в FragmentManager, это означает, что он находится в нужном месте и готов к использованию (вот почему вы можете захотеть получить ссылку на него , вызовите на нем методы, инициализируйте некоторые его свойства и т. д.). что хранится? - что сохраняется в onSaveInstanceState (), а данные хранятся в setArguments ().
user 20.05.2018 07:56

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

Damn Vegetables 21.05.2018 17:37
1
2
171
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

setRetainInstance (истина)

Управляйте сохранением экземпляра фрагмента при повторном создании Activity (например, при изменении конфигурации). Это можно использовать только с фрагментами, не находящимися в заднем стеке. Если установлено, жизненный цикл фрагмента будет немного отличаться при воссоздании действия:

onDestroy () не будет вызываться (но onDetach () все равно будет, потому что фрагмент отключается от его текущей активности).

onCreate (пакет) не будет вызываться, поскольку фрагмент не создается повторно.

onAttach (Активность) и onActivityCreated (пакет) по-прежнему будут вызываться.

Ответ принят как подходящий

Я потратил несколько часов, пытаясь воссоздать вашу ситуацию с различными сценариями. Прежде всего, я должен отметить, что жизненный цикл фрагментов на самом деле настолько сложен, что во время Google I / O 2018 один из ведущих разработчиков спросил аудиторию, вызывается ли метод onCreate() в Activity первым или в методе Fragment. И ответ был таким, что это зависит от версии SDK. Но они все больше и больше сосредотачиваются на библиотеках совместимости и советуют разработчикам использовать их, чтобы иметь универсальный опыт работы на разных устройствах, а также наслаждаться новыми API, которые будут выполнять работу по работе с фрагментами, что намного проще для нас.

Изучая документацию класса AppCompatActivity, я понял, что такое поведение - их способ работы с фрагментами.

Protected methods
void    onCreate(Bundle savedInstanceState)
Perform initialization of all fragments.

void    onDestroy()
Destroy all fragments.

void    onPostCreate(Bundle savedInstanceState)
void    onPostResume()
Dispatch onResume() to fragments.

void    onSaveInstanceState(Bundle outState)
Save all appropriate fragment state.

void    onStart()
Dispatch onStart() to all fragments.

void    onStop()
Dispatch onStop() to all fragments.

Как видите, они «сохраняют все соответствующие состояния фрагментов» в onSaveInstanceState(); Это означает, что состояния будут восстановлены позже, после того, как Activity будет уничтожен и воссоздан заново. Таким образом, в onDestroy() все фрагменты уничтожаются, и когда Activity создается снова, они также воссоздаются. Чтобы убедиться, вы можете переопределить эти методы как в Fragment, так и в Activity и проверить результат. Если вы не проверяете FragmentManager на наличие уже прикрепленных фрагментов, метод onCreate() для Fragment будет вызываться дважды: один раз непосредственно вами - добавляя как новый Fragment - и один раз самим AppCompatActivity.

Что касается retainInstance = true, в документации говорится, что он сохраняет переменные-члены во время изменений конфигурации и вызывает небольшую разницу в жизненном цикле Fragment.

Другие вопросы по теме