Android多Fragment新闻应用启动报Error inflating class fragment错误如何解决
问题根因
你看到的Error inflating class fragment只是表层报错,真实错误可以直接从日志的最底层Caused by栈找到:
kotlin.UninitializedPropertyAccessException: lateinit property viewModel has not been initialized
触发原因是BreakNewsFragment的onViewCreated方法里,在Activity还没完成viewModel初始化的时候就提前访问了这个属性。
问题触发逻辑
Android Activity的onCreate执行顺序是:
- 调用
super.onCreate - 执行
setContentView:这一步会解析XML布局,加载布局中写死的fragment标签,同时初始化NavHost导航里的首页Fragment(也就是你的BreakNewsFragment),触发它的onViewCreated生命周期 - 你原来的代码里,
viewModel的初始化是在setContentView之后才执行的,所以Fragment访问viewModel的时候,这个lateinit属性还没有被赋值,直接抛出未初始化异常。
解决方案
任选一种即可:
方案1:调整Activity初始化顺序(改造成本最低)
把viewModel的初始化逻辑移到setContentView之前,修改后的NewsActivity代码如下:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // viewModel初始化移到setContentView前面 val newsRepository = NewsRepository(ArticleDatabase(this)) val viewModelProviderFactory = NewsViewModelProviderFactory(newsRepository) viewModel = ViewModelProvider(this, viewModelProviderFactory).get(NewsViewModel::class.java) setContentView(R.layout.activity_news) bottomNavigationView.setupWithNavController(newsNavHostFragment.findNavController()) }
方案2:Fragment使用官方委托获取ViewModel(更规范)
不要在Fragment里强转Activity再拿ViewModel,改用Jetpack提供的activityViewModels委托自动获取共享ViewModel,会自动等待ViewModel初始化完成,不会出现未初始化问题。
在BreakNewsFragment中添加如下代码即可:
// 导入依赖 import androidx.fragment.app.activityViewModels // 类内部声明viewModel private val viewModel: NewsViewModel by activityViewModels()
后续排查建议
以后遇到布局inflate相关报错,不要只看表层的InflateException,一定要往下翻完整的异常栈,最底层的Caused by才是真实的错误原因。
内容的提问来源于stack exchange,提问作者Derefaa Cline
相关产品推荐
相关产品推荐

