kotlin.KotlinNullPointerException从本地会议室数据库访问数据时?

问题描述 投票:0回答:1

我是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()
}
database kotlin nullpointerexception retrofit android-room
1个回答
0
投票

您的代码中有两个问题。第一个很清楚,您正在尝试访问一个空对象,并且正在获取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

希望这对您有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.