Android单Activity多Fragment架构下FragmentContainerView加载异常问题
问题根源
你布局中的FragmentContainerView配置了app:navGraph属性,当Activity执行ActivityMainBinding.inflate(layoutInflater)加载布局时,会直接创建导航图中配置的起始Fragment,同步触发该Fragment的onCreate生命周期。而你当前的代码顺序是先加载布局,再执行User.initSharedPref(this)初始化,Fragment调用loadList时sharedPref还未完成初始化,触发UninitializedPropertyAccessException异常,最终导致布局加载失败,抛出Error inflating class androidx.fragment.app.FragmentContainerView错误。这也是你第二个打印日志没有输出的原因:崩溃发生在inflate阶段,还没执行到后续打印代码。
解决方法
- 调整初始化顺序(最直接)
将User.initSharedPref的调用位置提前到布局加载之前,保证Fragment创建前SharedPreference已经完成初始化:
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) println("Activity creation") // 提前初始化SharedPreference User.initSharedPref(this) val binding = ActivityMainBinding.inflate(layoutInflater) println("Activity creation part 2") setContentView(binding.root) setSupportActionBar(binding.toolbar) } }
- 延后Fragment加载逻辑
将Fragment中加载列表的代码从onCreate移到onViewCreated或更晚的生命周期节点,此时Activity的初始化逻辑已经执行完成,SharedPreference已经完成初始化:
private lateinit var mylist: MutableList<String> override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) mylist = User.loadScenarioList() }
- 补充User类安全校验
将sharedPref的声明从lateinit改为可空类型,增加未初始化的异常提示,避免后续出现相同问题时难以定位:
object User { private var sharedPref : SharedPreferences? = null fun initSharedPref(context: Context){ sharedPref = context.getSharedPreferences("JeuDePisteKtPreferenceFileKey",Context.MODE_PRIVATE) } fun loadList(): MutableList<String> { val pref = sharedPref ?: throw IllegalStateException("请先调用User.initSharedPref完成初始化") val json = pref.getString(KEY_LIST, "") ?: "" if (json == "") return mutableListOf() return Json.decodeFromString(json) } }
另外注意你代码中MutableList<String>后多写了一个>符号,需要修正避免编译错误。
内容的提问来源于stack exchange,提问作者Foxhunt
相关产品推荐
相关产品推荐

