Android Adapter加Context参数后报FragmentContainerView inflate错误求助
Adapter传入Context触发Activity启动崩溃问题
问题现象
在Adapter的构造函数中新增Context context参数后,在Fragment内初始化Adapter实例、通过requireContext()传入上下文参数时,直接触发Activity启动失败的崩溃。此前在社区找到的零散解决方案均未生效。
错误日志
java.lang.RuntimeException: Unable to start activity ComponentInfo{space.rodionov.swedishdriller/space.rodionov.swedishdriller.MainActivity}: android.view.InflateException: Binary XML file line #18 in space.rodionov.swedishdriller:layout/activity_main: Binary XML file line #18 in space.rodionov.swedishdriller:layout/activity_main: Error inflating class androidx.fragment.app.FragmentContainerView
相关代码片段
存在问题的Fragment代码
@AndroidEntryPoint class DrillerFragment : Fragment(R.layout.cardstack_layout), CardStackListener { private val viewModel: DrillerViewModel by viewModels() private var drillerAdapter = JavaDrillerAdapter(JavaDrillerAdapter.JavaDrillerDiff(), false, requireContext()) }
修改后的Adapter代码
public class JavaDrillerAdapter extends ListAdapter<Word, JavaDrillerAdapter.JavaDrillerViewHolder> { private Boolean nativToForeign; Context context; protected JavaDrillerAdapter(@NonNull DiffUtil.ItemCallback diffCallback, Boolean nativToForeign, Context context) { super(diffCallback); this.nativToForeign = nativToForeign; this.context = context; } }
报错指向的布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <androidx.appcompat.widget.Toolbar //省略无关代码 /> <!-- 报错日志指向的第18行布局节点 --> <androidx.fragment.app.FragmentContainerView android:id="@+id/nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@id/bottom_nav" android:layout_below="@id/toolbar" app:defaultNavHost="true" app:navGraph="@navigation/nav_graph" /> <com.google.android.material.bottomnavigation.BottomNavigationView //省略无关代码 /> </RelativeLayout>
承载页面MainActivity代码
class MainActivity : AppCompatActivity() { private lateinit var navController: NavController override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment navController = navHostFragment.findNavController() //后续导航逻辑省略 } }
问题根因
- 核心是Fragment生命周期时序错位:Fragment的成员变量赋值操作,发生在Fragment实例刚被创建、还未通过
onAttach绑定宿主上下文的阶段 - 该阶段调用
requireContext()会直接抛出状态异常,而这个异常发生在NavHostFragment通过导航图加载目标Fragment的过程中,最终被层层包装成FragmentContainerView的布局加载异常,很容易将排查方向误导到布局文件本身的问题上
修复方案
- 将Adapter的初始化逻辑从成员声明位置,移动到Fragment生命周期的安全阶段(比如
onViewCreated、onAttach等已完成上下文绑定的回调中) - 禁止在Fragment类实例化、成员初始化、自定义构造函数阶段调用
requireContext()、requireActivity()这类强依赖上下文绑定状态的方法 - 若需要向Adapter传递Context,可在视图创建完成后,通过
view.context获取实例传入,避开时序问题
正确初始化参考写法:
private var drillerAdapter: JavaDrillerAdapter? = null override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) drillerAdapter = JavaDrillerAdapter( JavaDrillerAdapter.JavaDrillerDiff(), false, requireContext() ) }
内容的提问来源于stack exchange,提问作者Alex Rodionow
相关产品推荐
相关产品推荐

