Как создать базу данных комнат на Android - PullRequest
1 голос
/ 25 мая 2020

В моем проекте есть Recycler, который получает информационный фильм в файл и сохраняет избранное в базе данных. Я использовал базу данных комнат, но она вернула ссылку на нулевой объект:

import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import com.example.week3.dao.MovieDao
import com.example.week3.model.movie

@Database(entities = [movie::class], version = 5,exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
    abstract fun movieDao():MovieDao
    companion object {
        @Volatile
        private var INSTANCE: AppDatabase? = null
        private val LOCK=Any()
        private val DB_NAME = "movie_favorite_db"
        operator fun invoke(context: Context)= INSTANCE?: synchronized(LOCK){
            INSTANCE?: getDatabase(context).also {
                INSTANCE=it
            }
        }
        fun getDatabase(context: Context) = Room.databaseBuilder(
                    context.applicationContext,
                    AppDatabase::class.java,
                    DB_NAME
                ).allowMainThreadQueries()
            .build() // alway return null

            }
}

И комната для вызовов репозитория:

package com.example.week3.data

import android.app.Application
import com.example.week3.model.listMovieAndInfo
import com.example.week3.model.movie
import com.google.gson.Gson
import com.khtn.androidcamp.DataCenter

class dataRepositories(application:Application) {
    val moviesDao = AppDatabase.invoke(application).movieDao()
    val listMovieFavorite=moviesDao.getAllTasks()
    fun getListMovie(): MutableList<movie> {
        var listMovie= mutableListOf<movie>()
        val gson=Gson();
        val listMoiveIfo=gson.fromJson<listMovieAndInfo>(DataCenter.getMovieJsonString(),listMovieAndInfo::class.java);
        if (listMoiveIfo.total_pages>0){
            listMovie=listMoiveIfo.results
        }
        return listMovie
    }
    suspend fun deleteMovieFavorite(movie: movie){
        moviesDao.deleteMovie(movie)
    }
    suspend fun insertMovieFavorite(movie: movie){
        moviesDao.insertMovie(movie)
    }
}

Я наблюдаю во фрагменте:

package com.example.week3.view

import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.GridLayoutManager

import com.example.week3.R
import com.example.week3.adapter.rv_adapter
import com.example.week3.data.dataRepositories
import com.example.week3.model.movie
import com.example.week3.viewmodel.MovieViewModel
import kotlinx.android.synthetic.main.fragment_now_playing.*


class NowPlayingFragment : Fragment() {
    private lateinit var movieFavoriteViewModel: MovieViewModel
    var listMovie = listOf<movie>()
    var rv_layoutManager= GridLayoutManager(activity,1)
    var rv_adapter_list_film= rv_adapter(listMovie,rv_layoutManager);
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_now_playing, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        setContent()

    }

    private fun setContent() {
        movieFavoriteViewModel= ViewModelProvider(this).get(MovieViewModel::class.java)
        listMovie=movieFavoriteViewModel.listAllMovie
        setRecyclerView()

    }

    private fun setRecyclerView() {
        rv_list_film_now_playing.layoutManager=rv_layoutManager
        rv_list_film_now_playing.adapter=rv_adapter_list_film
        rv_adapter_list_film.listener=object :rv_adapter.OnItemClickListener{
            override fun onItemClick(item: movie) {
                val intent= Intent(activity,filmDetailActivity::class.java);
                //intent.putExtra("film_detail",item)
                startActivity(intent)
            }

            override fun onStartItemToggle(item: movie) {

            }
        }
    }

}

Это ошибка, которую я получаю при запуске:


D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.week3, PID: 15927
    java.lang.RuntimeException: Cannot create an instance of class com.example.week3.viewmodel.MovieViewModel
        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:275)
        at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:106)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
        at com.example.week3.view.NowPlayingFragment.setContent(NowPlayingFragment.kt:45)
        at com.example.week3.view.NowPlayingFragment.onActivityCreated(NowPlayingFragment.kt:40)
        at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2717)
        at androidx.fragment.app.FragmentStateManager.activityCreated(FragmentStateManager.java:336)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1186)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1354)
        at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1432)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1495)
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:447)
        at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2167)
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1990)
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1945)
        at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1847)
        at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:237)
        at android.app.ActivityThread.main(ActivityThread.java:7860)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075)
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Constructor.newInstance0(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:267)
        at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:106) 
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185) 
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150) 
        at com.example.week3.view.NowPlayingFragment.setContent(NowPlayingFragment.kt:45) 
        at com.example.week3.view.NowPlayingFragment.onActivityCreated(NowPlayingFragment.kt:40) 
        at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2717) 
        at androidx.fragment.app.FragmentStateManager.activityCreated(FragmentStateManager.java:336) 
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1186) 
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1354) 
        at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1432) 
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1495) 
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:447) 
        at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2167) 
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1990) 
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1945) 
        at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1847) 
        at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413) 
        at android.os.Handler.handleCallback(Handler.java:883) 
        at android.os.Handler.dispatchMessage(Handler.java:100) 
        at android.os.Looper.loop(Looper.java:237) 
        at android.app.ActivityThread.main(ActivityThread.java:7860) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075) 
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Package.getName()' on a null object reference
        at androidx.room.Room.getGeneratedImplementation(Room.java:79)
        at androidx.room.RoomDatabase$Builder.build(RoomDatabase.java:952)
        at AppDatabase$Companion.getDatabase(AppDatabase.kt:26)
        at AppDatabase$Companion.invoke(AppDatabase.kt:17)
        at com.example.week3.data.dataRepositories.<init>(dataRepositories.kt:10)
        at com.example.week3.viewmodel.MovieViewModel.<init>(MovieViewModel.kt:14)
        at java.lang.reflect.Constructor.newInstance0(Native Method) 
        at java.lang.reflect.Constructor.newInstance(Constructor.java:343) 
        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:267) 
        at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:106) 
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185) 
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150) 
        at com.example.week3.view.NowPlayingFragment.setContent(NowPlayingFragment.kt:45) 
        at com.example.week3.view.NowPlayingFragment.onActivityCreated(NowPlayingFragment.kt:40) 
        at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2717) 
        at androidx.fragment.app.FragmentStateManager.activityCreated(FragmentStateManager.java:336) 
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1186) 
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1354) 
        at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1432) 
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1495) 
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:447) 
        at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2167) 
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1990) 
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1945) 
        at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1847) 
        at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413) 
        at android.os.Handler.handleCallback(Handler.java:883) 
        at android.os.Handler.dispatchMessage(Handler.java:100) 
        at android.os.Looper.loop(Looper.java:237) 
        at android.app.ActivityThread.main(ActivityThread.java:7860) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1075) 


Я пытался исправить это с помощью точки отладки, но это не помогло, Room всегда возвращает null.

...