Lateinit属性尚未在片段的onSaveInstanceState

时间:2019-10-24 20:27:20

标签: java android android-fragments

我有一个用片段构建的活动。现在,我想在onSaveInstanceState中保存一些小部件的数据。我会尝试总结一下情况。

这是我的活动:

Activity.kt:

class Activity: AppCompatActivity() {

    private lateinit var fragment1: Fragment1
    private lateinit var fragment2: Fragment2
    private lateinit var fragment3: Fragment3

    override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
        super.onCreate(savedInstanceState, persistentState)
        setContentView(R.layout.activity)

        if(savedInstanceState != null) {
            if(supportFragmentManager.getFragment(savedInstanceState, "fragment1") != null)
                fragment1 = supportFragmentManager.getFragment(savedInstanceState, "fragment1") as Fragment1
            else fragment1 = Fragment1()
            if(supportFragmentManager.getFragment(savedInstanceState, "fragment2") != null)
                fragment2 = supportFragmentManager.getFragment(savedInstanceState, "fragment2") as Fragment2
            else fragment2 = Fragment2()
            if(supportFragmentManager.getFragment(savedInstanceState, "fragment3") != null)
                fragment3 = supportFragmentManager.getFragment(savedInstanceState, "fragment3") as Fragment3
            else fragment3 = Fragment3()
        } else {
            fragment1 = Fragment1()
            fragment2 = Fragment2()
            fragment3 = Fragment3()

            supportFragmentManager
                .beginTransaction()
                .add(R.id.content_frame, fragment1)
                .commit()
        }
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        if(fragment1.isAdded)
            supportFragmentManager.putFragment(outState, "fragment1", fragment1)
        if(fragment2.isAdded)
            supportFragmentManager.putFragment(outState, "fragment2", fragment2)
        if(fragment3.isAdded)
            supportFragmentManager.putFragment(outState, "fragment3", fragment3)
    }

    fun addFragment2() {
        supportFragmentManager
            .beginTransaction()
            .addToBackStack(null)
            .replace(R.id.content_frame, fragment2)
            .commit()
    }

    fun addFragment3() {
        supportFragmentManager
            .beginTransaction()
            .addToBackStack(null)
            .replace(R.id.content_frame, fragment3)
            .commit()
    }
}

这是片段的实现。

Fragment2:

Fragment2.kt:

class Fragment2: Fragment() {

    private lateinit var customView: CustomView

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val view = inflater.inflate(R.layout.fragment2, container, false)

        customView = view.findViewById(R.id.custom_view)
        if(savedInstanceState != null) {
            customView.setIntValue(savedInstanceState.getInt("int_value"))
        }

        return view
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putInt("int_value", customView.intValue)
    }
}

这是片段2。因此,现在的情况如下。我叫addFragment2()addFragment3()。现在,我换到风景。称为以下回调方法:

  1. onSaveInstanceState在活动中
  2. {3}中的onSaveInstanceState
  3. 片段2中的
  4. onSaveInstanceState
  5. 片段1中的
  6. onSaveInstanceState
  7. onCreate在活动中
  8. {3}中的onCreate
  9. {3}中的onCreateView
  10. 片段2中的
  11. onCreate
  12. 片段1中的
  13. onCreate

在Fragment2和Fragment 1中,未调用onCreateView,因为这些片段不可见。

现在,我再次换成肖像。回调方法被再次调用。但是现在,在Fragment2中,我得到一个例外:lateinit property customView is not initialized。 (在customView.intValue中对onSaveInstanceState的调用中)我认为它是否是自定义小部件都没有关系,也可以仅使用TextView引发异常。

这对我来说很有意义。在活动的onSaveInstanceState中,fragment2.isAdded != nullfalse,因此片段不会保存到outState并在onCreate中再次实例化。然后,不调用Fragment2中的onCreateView,因此未初始化customView。现在,当调用Fragment2中的onSaveInstanceState时,对customView的调用将引发异常。

所以,我了解为什么这行不通,但是我不知道如何使它生效。片段是否以错误的方式实现和保存?有没有一种方法可以保存所有片段实例,而不仅仅是当前最上面的片段?

代码只是一个应总结我的问题的示例。如果您需要更多代码,我可以对其进行编辑。

0 个答案:

没有答案