使用 SQLite 数据库启动应用程序时出现 NullPointerException
NullPointerException on Application startup using SQLite database
我对 Kotlin 和 SQLite 比较陌生,我使用 android studio 制作的应用程序不断产生 NullPointerReference 错误。
我的应用程序从用户那里获取输入并将其存储到 SQLite 数据库中。然后它将条目加载到主页上。当 运行 我的应用程序第一次出现时,它会产生以下错误。
Logcat
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.reminders/com.example.reminders.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.File android.content.Context.getDatabasePath(java.lang.String)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3654)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3806)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2267)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8167)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.File android.content.Context.getDatabasePath(java.lang.String)' on a null object reference
at android.content.ContextWrapper.getDatabasePath(ContextWrapper.java:337)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:445)
at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:415)
at com.example.reminders.FeedReaderDbHelper.viewReminder(DatabaseHandler.kt:61)
at com.example.reminders.HistoryActivity.getItemsList(HistoryActivity.kt:37)
at com.example.reminders.HistoryActivity.setupListofDataintoRecyclerView(HistoryActivity.kt:20)
at com.example.reminders.MainActivity.onCreate(MainActivity.kt:99)
at android.app.Activity.performCreate(Activity.java:7963)
at android.app.Activity.performCreate(Activity.java:7952)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3629)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3806)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2267)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8167)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
来自我的 MainActivity 的相关代码
class MainActivity : AppCompatActivity() {
lateinit var alarmService: AlarmService
lateinit var historyActivity: HistoryActivity
@RequiresApi(Build.VERSION_CODES.N)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.history_main)
createNotificationChannel()
alarmService = AlarmService(this)
historyActivity = HistoryActivity()
...
}
historyActivity.setupListofDataintoRecyclerView(this)
}
启动时,我打算让它检查数据库中的项目数是否 > 0。如果大于 0,应用程序将加载数据库。没有则显示没有条目
来自我的 HistoryActivity 的相关代码
fun setupListofDataintoRecyclerView(context: Context) {
if (getItemsList().size > 0) {
tvEmptyHistory.visibility = View.GONE
rvHistory.visibility = View.VISIBLE
rvHistory.layoutManager = LinearLayoutManager(context)
var itemAdapter = HistoryAdapter(context, getItemsList())
rvHistory.adapter = itemAdapter
}
else {
tvEmptyHistory.visibility = View.VISIBLE
rvHistory.visibility = View.GONE
}
}
private fun getItemsList(): ArrayList<reminderHistory> {
//create instance of DatabaseHandler
val databaseHandler = FeedReaderDbHelper(this)
//call method to view database
return databaseHandler.viewReminder()
}
来自我的 FeedReaderDbHelper 的相关代码 class
class FeedReaderDbHelper(context: Context) :
SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
...
fun viewReminder(): ArrayList<reminderHistory> {
val rHistList: ArrayList<reminderHistory> = ArrayList()
val selectQuery = "SELECT * FROM $TABLE_CONTACTS"
val db = this.readableDatabase
var cursor: Cursor? = null
try {
cursor = db.rawQuery(selectQuery, null)
} catch (e: SQLiteException) {
db.execSQL(selectQuery)
return ArrayList()
}
var id: Int
var item: String
var hour: Int
var min: Int
var date: String
if (cursor.moveToFirst()) {
do {
id = cursor.getInt((cursor.getColumnIndex(KEY_ID)))
item = cursor.getString(cursor.getColumnIndex(KEY_ITEM))
hour = cursor.getInt(cursor.getColumnIndex(KEY_HOUR))
min = cursor.getInt(cursor.getColumnIndex(KEY_MIN))
date = cursor.getString(cursor.getColumnIndex(KEY_DATE))
val reminder =
reminderHistory(id = id, item = item, hour = hour, min = min, date = date)
rHistList.add(reminder)
} while (cursor.moveToNext())
}
cursor.close()
return rHistList
}
...
下面的错误行
at com.example.reminders.FeedReaderDbHelper.viewReminder(DatabaseHandler.kt:61)
指的是行val db = this.readableDatabase
我不确定问题出在上下文为空(属于 class)还是数据库。
请就此提出任何建议或意见。
谢谢。
您以错误的方式调用 historyActivity,请尝试使用 intent 打开 activity。尝试使用以下代码实现。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.history_main)
createNotificationChannel()
alarmService = AlarmService(this)
val intent = Intent(this, HistoryActivity::class.java)
startActivity(intent)
}
我对 Kotlin 和 SQLite 比较陌生,我使用 android studio 制作的应用程序不断产生 NullPointerReference 错误。
我的应用程序从用户那里获取输入并将其存储到 SQLite 数据库中。然后它将条目加载到主页上。当 运行 我的应用程序第一次出现时,它会产生以下错误。
Logcat
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.reminders/com.example.reminders.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.File android.content.Context.getDatabasePath(java.lang.String)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3654)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3806)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2267)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8167)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.File android.content.Context.getDatabasePath(java.lang.String)' on a null object reference
at android.content.ContextWrapper.getDatabasePath(ContextWrapper.java:337)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:445)
at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:415)
at com.example.reminders.FeedReaderDbHelper.viewReminder(DatabaseHandler.kt:61)
at com.example.reminders.HistoryActivity.getItemsList(HistoryActivity.kt:37)
at com.example.reminders.HistoryActivity.setupListofDataintoRecyclerView(HistoryActivity.kt:20)
at com.example.reminders.MainActivity.onCreate(MainActivity.kt:99)
at android.app.Activity.performCreate(Activity.java:7963)
at android.app.Activity.performCreate(Activity.java:7952)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3629)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3806)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2267)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8167)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
来自我的 MainActivity 的相关代码
class MainActivity : AppCompatActivity() {
lateinit var alarmService: AlarmService
lateinit var historyActivity: HistoryActivity
@RequiresApi(Build.VERSION_CODES.N)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.history_main)
createNotificationChannel()
alarmService = AlarmService(this)
historyActivity = HistoryActivity()
...
}
historyActivity.setupListofDataintoRecyclerView(this)
}
启动时,我打算让它检查数据库中的项目数是否 > 0。如果大于 0,应用程序将加载数据库。没有则显示没有条目
来自我的 HistoryActivity 的相关代码
fun setupListofDataintoRecyclerView(context: Context) {
if (getItemsList().size > 0) {
tvEmptyHistory.visibility = View.GONE
rvHistory.visibility = View.VISIBLE
rvHistory.layoutManager = LinearLayoutManager(context)
var itemAdapter = HistoryAdapter(context, getItemsList())
rvHistory.adapter = itemAdapter
}
else {
tvEmptyHistory.visibility = View.VISIBLE
rvHistory.visibility = View.GONE
}
}
private fun getItemsList(): ArrayList<reminderHistory> {
//create instance of DatabaseHandler
val databaseHandler = FeedReaderDbHelper(this)
//call method to view database
return databaseHandler.viewReminder()
}
来自我的 FeedReaderDbHelper 的相关代码 class
class FeedReaderDbHelper(context: Context) :
SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
...
fun viewReminder(): ArrayList<reminderHistory> {
val rHistList: ArrayList<reminderHistory> = ArrayList()
val selectQuery = "SELECT * FROM $TABLE_CONTACTS"
val db = this.readableDatabase
var cursor: Cursor? = null
try {
cursor = db.rawQuery(selectQuery, null)
} catch (e: SQLiteException) {
db.execSQL(selectQuery)
return ArrayList()
}
var id: Int
var item: String
var hour: Int
var min: Int
var date: String
if (cursor.moveToFirst()) {
do {
id = cursor.getInt((cursor.getColumnIndex(KEY_ID)))
item = cursor.getString(cursor.getColumnIndex(KEY_ITEM))
hour = cursor.getInt(cursor.getColumnIndex(KEY_HOUR))
min = cursor.getInt(cursor.getColumnIndex(KEY_MIN))
date = cursor.getString(cursor.getColumnIndex(KEY_DATE))
val reminder =
reminderHistory(id = id, item = item, hour = hour, min = min, date = date)
rHistList.add(reminder)
} while (cursor.moveToNext())
}
cursor.close()
return rHistList
}
...
下面的错误行
at com.example.reminders.FeedReaderDbHelper.viewReminder(DatabaseHandler.kt:61)
指的是行val db = this.readableDatabase
我不确定问题出在上下文为空(属于 class)还是数据库。 请就此提出任何建议或意见。 谢谢。
您以错误的方式调用 historyActivity,请尝试使用 intent 打开 activity。尝试使用以下代码实现。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.history_main)
createNotificationChannel()
alarmService = AlarmService(this)
val intent = Intent(this, HistoryActivity::class.java)
startActivity(intent)
}