面试题答案
一键面试实现过程
- 保存状态
- 使用
ViewModel
:在ViewModel
中定义变量来存储界面状态。例如,对于列表滚动位置,可以使用Int
类型变量记录当前滚动的偏移量;对于输入框内容,使用String
类型变量存储输入的文本。在onSaveInstanceState
方法被调用前,将这些状态数据更新到ViewModel
中。 onSaveInstanceState
:系统在配置更改(如切换暗黑模式)前会调用Activity
或Fragment
的onSaveInstanceState
方法。在该方法中,可以额外保存一些ViewModel
未处理的状态,比如自定义视图的特定状态等,通过outState
这个Bundle
对象来保存,例如outState.putInt("custom_view_state", customView.getState())
。
- 使用
- 恢复状态
ViewModel
恢复:在Activity
或Fragment
重建后,获取ViewModel
实例。ViewModel
在配置更改时不会被销毁,其保存的状态数据依然存在。例如,对于列表,根据ViewModel
中保存的滚动偏移量,使用RecyclerView
的scrollToPosition
等方法恢复滚动位置;对于输入框,设置EditText
的文本为ViewModel
中保存的文本。onRestoreInstanceState
:Activity
或Fragment
重建后,系统会调用onRestoreInstanceState
方法,并传入之前onSaveInstanceState
保存的Bundle
对象。在该方法中,可以从Bundle
中取出之前保存的自定义状态数据,并恢复到相应的视图中,如customView.setState(savedInstanceState.getInt("custom_view_state"))
。
可能遇到的难点及解决方案
- 复杂视图状态保存
- 难点:对于复杂的自定义视图,其状态可能难以简单地用基本数据类型表示和保存。例如,一个带有多层嵌套子视图且各子视图有不同状态的自定义容器视图。
- 解决方案:在自定义视图中添加
saveState
和restoreState
方法。saveState
方法返回一个包含所有子视图状态的Parcelable
对象或Bundle
,restoreState
方法根据传入的Parcelable
对象或Bundle
恢复视图状态。在onSaveInstanceState
和onRestoreInstanceState
中调用这些自定义视图的方法来保存和恢复复杂状态。
- 数据一致性问题
- 难点:在保存和恢复状态过程中,可能出现数据不一致。比如,在保存状态后,后台线程对数据进行了修改,而恢复状态时使用了旧数据。
- 解决方案:在保存状态前,暂停可能修改相关数据的后台线程。可以使用
LiveData
等机制,当状态恢复后,重新订阅数据更新,确保界面显示的数据是最新的。同时,在ViewModel
中对数据的修改操作添加同步机制,保证数据一致性。
- 多Fragment交互状态管理
- 难点:当应用中有多个
Fragment
相互交互,且每个Fragment
都有自己的状态,在切换暗黑模式时,如何确保各Fragment
状态恢复后能正确交互。例如,一个Fragment
中列表的选中项影响另一个Fragment
的显示内容。 - 解决方案:使用共享的
ViewModel
来管理跨Fragment
的状态数据。每个Fragment
在保存和恢复自身状态时,同时与共享ViewModel
中的数据进行交互和同步。在状态恢复后,通过Fragment
之间的通信机制(如SharedViewModel
结合LiveData
)来确保各Fragment
之间的交互状态正确。
- 难点:当应用中有多个