我是Kotlin的新手,正在尝试学习如何通过改装来获取数据并将此数据存储到Room DB中。但是,一旦我开始执行该过程的活动,我就会得到NullPointerException。
编辑:据我所知,即使我有重写oncreate函数的地方,我想访问它时,RoomViewmodel类中的“数据库”仍然为NULL
这里也是我正在从事的小型项目中到GitHub存储库的链接:https://github.com/Engin92/Dog_Breeds/tree/RoomDatabase
这是我完整的错误列表:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.dogbreeds, PID: 14803
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.dogbreeds/com.example.Breedlist.activity.DetailedViewActivity}: kotlin.KotlinNullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3782)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3961)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:91)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:103)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2386)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:8178)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)
Caused by: kotlin.KotlinNullPointerException
at com.example.Breedlist.activity.DetailedViewActivityRepository.getBreeds(DetailedViewActivityRepository.kt:23)
at com.example.Breedlist.activity.DetailedViewActivityViewModel.getAllBreedList(DetailedViewActivityViewModel.kt:23)
at com.example.Breedlist.activity.DetailedViewActivity.onCreate(DetailedViewActivity.kt:42)
at android.app.Activity.performCreate(Activity.java:8086)
at android.app.Activity.performCreate(Activity.java:8074)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1313)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3755)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3961)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:91)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:103)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2386)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:8178)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)
DetailedViewActivity的重要部分
class DetailedViewActivity : AppCompatActivity() {
lateinit var breedRecyclerView: RecyclerView
lateinit var detailedViewActivityViewModel: DetailedViewActivityViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_detailed_view)
breedRecyclerView = findViewById(R.id.breedRecyclerView)
detailedViewActivityViewModel = ViewModelProviders.of(this).get(
DetailedViewActivityViewModel::class.java)
if(isOnline(this))
{
detailedViewActivityViewModel.getBreedsFromAPIAndStore()
}
else
{
Toast.makeText(this,"No internet connection. Showing cached list!",Toast.LENGTH_LONG).show()
}
detailedViewActivityViewModel.getAllBreedList().observe(this, Observer<List<CurrentBreedResponseItem>> { breedList ->
Log.e(MainActivity::class.java.simpleName,breedList.toString())
setUpBreedRecyclerView(breedList!!)
})
} ....
类RoomViewModel,我在其中构建数据库(我认为错误出在哪里,在尝试访问(写入/读取)它之后,var数据库仍然为NULL)
class RoomViewModel : Application() {
companion object {
var database: BreedDatabase? = null
}
override fun onCreate() {
super.onCreate()
database = Room.databaseBuilder(applicationContext, BreedDatabase::class.java, "breed_db").fallbackToDestructiveMigration().build()
}
}
DetailedViewActivityRepository中的getBreeds函数:
fun getBreeds() : LiveData<List<CurrentBreedResponseItem>>
{
return RoomViewModel.database!!.currentBreedDao().getAllBreeds()
}
DetailedViewActivityViewModel中的getAllBreedList函数
fun getAllBreedList(): LiveData<List<CurrentBreedResponseItem>>
{
return detailedViewActivityRepository.getBreeds()
}
您的代码中有两个问题。第一个很清楚,您正在尝试访问一个空对象,并且正在获取NullPointerException。因此,在使用!!
运算符时要小心。
得到它的原因是,在RoomViewModel内部,数据库实例为null。
class RoomViewModel : Application() {
companion object {
var database: BreedDatabase? = null
}
override fun onCreate() {
super.onCreate()
database = Room.databaseBuilder(applicationContext, BreedDatabase::class.java, "breed_db")
.fallbackToDestructiveMigration().build()
}
}
您可能认为您正在初始化onCreate()
中的数据库实例,但未调用onCreate()
。原因是要使应用程序类正常工作,您需要将其添加到AndroidManifest.xml文件中。
解决方案:
将这样的RoomViewModel
类添加到您的AndroidManifest.xml文件中。
<application
android:name=".view.RoomViewModel"
android:allowBackup="true"
我们将其用作应用程序标签的name属性,如您在上面看到的。这将修复您的空指针异常。但是您的程序将再次崩溃,因为您使用的是Kotlin,并且确实为kotlin腾出了空间,因此需要在应用程序级别build.gradle文件中添加此内容。
kapt "android.arch.persistence.room:compiler:1.1.1"
将其添加到依赖项块内的应用程序级别build.gradle后。同步您的项目并运行它应该可以工作。
如果要了解有关Android中Room Room的更多信息,可以选中此Room Database Tutorial。
希望这对您有帮助。