Android Room初始化调用getApplicationContext出现空指针异常如何解决?
问题引发原因
空指针错误来源于MainActivity中dao属性的初始化时机错误:
- Activity的Context上下文只有在系统回调
onCreate()方法之后才会完成初始化、处于可用状态 - 你将
private val dao:TaskDao = TaskDataBase.getInstance(this).taskDao写为类的成员属性,类属性的初始化会在onCreate()执行前完成,此时传入的this(Activity实例)还未绑定有效Context,所以在Room实例构建调用context.applicationContext时就触发了空指针。
修复方案
以下两种方案任选其一即可解决问题:
方案1:在onCreate中初始化dao
将dao的声明改为lateinit var,在onCreate中完成赋值,此时Context已经处于可用状态:
class MainActivity : AppCompatActivity(), TodoAdapter.OnItemLongClickListener { private var todoList = mutableListOf( Todo("First Todo item", false), Todo("Second Todo item", true), Todo("Third Todo item", false), Todo("Forth Todo item", true), Todo("Fifth Todo item", false), Todo("Sixth Todo item", true), Todo("Seventh Todo item", false) ) private val adapter = TodoAdapter(todoList, this) // 改为lateinit延迟初始化 private lateinit var dao:TaskDao override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 在此处初始化dao dao = TaskDataBase.getInstance(this).taskDao rvTodos.adapter = adapter rvTodos.layoutManager = LinearLayoutManager(this) // 原有后续逻辑 } }
方案2:使用lazy懒加载初始化dao
利用Kotlin的lazy属性特性,只有第一次调用dao的时候才会执行初始化逻辑,此时Activity已经走完onCreate生命周期,Context有效:
class MainActivity : AppCompatActivity(), TodoAdapter.OnItemLongClickListener { private var todoList = mutableListOf( Todo("First Todo item", false), Todo("Second Todo item", true), Todo("Third Todo item", false), Todo("Forth Todo item", true), Todo("Fifth Todo item", false), Todo("Sixth Todo item", true), Todo("Seventh Todo item", false) ) private val adapter = TodoAdapter(todoList, this) // 使用lazy懒加载 private val dao:TaskDao by lazy { TaskDataBase.getInstance(this).taskDao } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) rvTodos.adapter = adapter rvTodos.layoutManager = LinearLayoutManager(this) // 原有后续逻辑 } }
内容的提问来源于stack exchange,提问作者Awni Ahmed
相关产品推荐
相关产品推荐

