基于Room数据库的提醒APP出现NullPointerException问题求助
Room数据库空指针异常:databaseClass对象未初始化
我跟着YouTube教程开发基于Room的提醒APP,运行时抛出空指针异常:
java.lang.NullPointerException: Attempt to invoke virtual method 'com.dev.alarmreminder.Database.EventDao com.dev.alarmreminder.Database.DatabaseClass.EventDao()' on a null object reference
错误堆栈:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'com.dev.alarmreminder.Database.EventDao com.dev.alarmreminder.Database.DatabaseClass.EventDao()' on a null object reference at com.dev.alarmreminder.MainActivity.setAdapter(MainActivity.java:49) at com.dev.alarmreminder.MainActivity.onResume(MainActivity.java:43)
问题出在MainActivity的setAdapter方法第一行,调用databaseClass.EventDao()时databaseClass对象为空。以下是相关代码:
DatabaseClass.java
@Database(entities = {EntityClass.class}, version = 1) public abstract class DatabaseClass extends RoomDatabase { public abstract EventDao EventDao(); private static DatabaseClass INSTANCE; static DatabaseClass getDatabase(final Context context) { if(INSTANCE == null) { synchronized (DatabaseClass.class) { if(INSTANCE == null) { INSTANCE = Room.databaseBuilder(context.getApplicationContext(), DatabaseClass.class, "product_database").build(); } } } return INSTANCE; } }
EventDao.java
import androidx.room.Dao; import androidx.room.Insert; import androidx.room.Query; import java.util.List; @Dao public interface EventDao { @Insert void insertAll(EntityClass entityClass); @Query("SELECT * FROM myTable") List<EntityClass> getAllData(); }
EntityClass.java
import androidx.room.Entity; import androidx.room.PrimaryKey; @Entity(tableName = "myTable") public class EntityClass { @PrimaryKey(autoGenerate = true) int id; String eventname; String eventdate; String eventtime; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getEventname() { return eventname; } public void setEventname(String eventname) { this.eventname = eventname; } public String getEventdate() { return eventdate; } public void setEventdate(String eventdate) { this.eventdate = eventdate; } public String getEventtime() { return eventtime; } public void setEventtime(String eventtime) { this.eventtime = eventtime; } }
MainActivity.java
package com.mahidev.alarmreminder; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.RecyclerView; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import com.mahidev.alarmreminder.Adapter.EventAdapter; import com.mahidev.alarmreminder.Database.DatabaseClass; import com.mahidev.alarmreminder.Database.EntityClass; import java.util.List; public class MainActivity extends AppCompatActivity implements View.OnClickListener { Button createEvent; EventAdapter eventAdapter; RecyclerView recyclerView; DatabaseClass databaseClass; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); createEvent = findViewById(R.id.btn_createEvent); recyclerView = findViewById(R.id.recyclerview); createEvent.setOnClickListener(this); } @Override protected void onResume() { super.onResume(); setAdapter(); } private void setAdapter() { List<EntityClass> classList = databaseClass.EventDao().getAllData(); eventAdapter = new EventAdapter(getApplicationContext(), classList); recyclerView.setAdapter(eventAdapter); } @Override public void onClick(View view) { if(view == createEvent) { goToCreateEventActivity(); } } private void goToCreateEventActivity() { Intent intent = new Intent(getApplicationContext(), CreateEvent.class); startActivity(intent); } }
解决方法
- 初始化databaseClass对象
问题核心是MainActivity中声明的databaseClass变量从未赋值,直接调用方法导致空指针。修改onCreate方法,通过DatabaseClass.getDatabase()获取实例:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); createEvent = findViewById(R.id.btn_createEvent); recyclerView = findViewById(R.id.recyclerview); createEvent.setOnClickListener(this); // 初始化数据库实例 databaseClass = DatabaseClass.getDatabase(this); }
- 异步执行数据库操作
Room禁止在主线程执行数据库查询,直接调用getAllData()会抛出异常,需用协程或AsyncTask处理异步操作。示例用协程修改setAdapter:
private void setAdapter() { // 在IO线程执行查询 CoroutineScope(Dispatchers.IO).launch { List<EntityClass> classList = databaseClass.EventDao().getAllData(); // 回到主线程更新UI runOnUiThread(() -> { eventAdapter = new EventAdapter(getApplicationContext(), classList); recyclerView.setAdapter(eventAdapter); }); } }
需确保项目已添加协程依赖,或使用其他异步方案替代。
内容的提问来源于stack exchange,提问作者Man Steel
相关产品推荐
相关产品推荐

