onCreate() 之前的 Activity 无法使用的系统服务:ROOM
System services not available to Activities before onCreate() : ROOM
我有这个 activity,当我点击一个图像时我有这个回调。它工作正常,但现在我补充说,如果单击它,它会将数据保存在数据库中。问题是,现在我收到系统服务不可用错误,我不确定如何修复它。有什么想法吗?
这是activity(我只展示了它的相关部分):
class MainActivity : AppCompatActivity(), RecyclerAdapter.Callback, androidx.appcompat.widget.SearchView.OnQueryTextListener {
private lateinit var binding: ActivityMainBinding
private val movies = mutableListOf<Movie>()
private lateinit var adapter: RecyclerAdapter
private lateinit var progressBar: ProgressBar
private lateinit var mMoviesViewModel: MoviesViewModel
private val viewModel: MainViewModel by viewModels(
factoryProducer = { MainViewModelFactory() }
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.svSearch.setOnQueryTextListener(this)
//setup progress bar
progressBar = binding.ProgressBar
progressBar.visibility = View.VISIBLE
setObservers()
initRecyclerView()
}
private fun initRecyclerView() {
adapter = RecyclerAdapter(movies)
binding.rvMovies.layoutManager = GridLayoutManager(this, 3)
binding.rvMovies.adapter = adapter
adapter.callback = this
}
//instantiate database for later
val db = Room.databaseBuilder(
this,
MoviesDatabase::class.java, "database-name"
).build()
val dao = db.moviesDao()
//send details of clicked movie to fragment
override fun onMovieClicked(movie: Movie) {
val transaction = supportFragmentManager
val detailFragment = DetailFragment()
val data = Bundle()
//check if movie is already in database
if(dao.movieExists(movie.id)){
//send movie's id to fragment
data.putString("Title", movie.title)
detailFragment.arguments = data
} else {
val title = movie.title
val image = movie.poster
val overview = movie.overview
val language = movie.originalLanguage
val releaseDate = movie.releaseDate
val popularity = movie.popularity
val voteAverage = movie.voteAverage
//create movie object
val movie = Movies(id =0, title, image, overview,
language, popularity, releaseDate, voteAverage
)
//add data to db
mMoviesViewModel.addMovie(movie)
//send movie's id to fragment
data.putString("Title", movie.title)
detailFragment.arguments = data
}
//pass data to fragment
transaction.beginTransaction()
.replace(R.id.frag_container, detailFragment)
.addToBackStack(null)
.commit()
}
}
堆栈跟踪:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.app.challengemovieapp.develop, PID: 13142
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.app.challengemovieapp.develop/com.app.challengemovieapp.ui.MainActivity}: java.lang.IllegalStateException: System services not available to Activities before onCreate()
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3032)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3269)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1960)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7094)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)
Caused by: java.lang.IllegalStateException: System services not available to Activities before onCreate()
at android.app.Activity.getSystemService(Activity.java:6143)
at androidx.room.RoomDatabase$JournalMode.resolve(RoomDatabase.java:663)
at androidx.room.RoomDatabase$Builder.build(RoomDatabase.java:1346)
at com.app.challengemovieapp.ui.MainActivity.<init>(MainActivity.kt:129)
at java.lang.Class.newInstance(Native Method)
at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:69)
at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45)
at android.app.Instrumentation.newActivity(Instrumentation.java:1219)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3020)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3269)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1960)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7094)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)
您需要移动这些行:
val db = Room.databaseBuilder(
this,
MoviesDatabase::class.java, "database-name"
).build()
val dao = db.moviesDao()
Room 需要调用 Context
上的方法,这些方法在您的 MainActivity
实例化时尚未就绪。在 onCreate()
函数 super.onCreate()
之前,您不应该尝试使用 Room。
我有这个 activity,当我点击一个图像时我有这个回调。它工作正常,但现在我补充说,如果单击它,它会将数据保存在数据库中。问题是,现在我收到系统服务不可用错误,我不确定如何修复它。有什么想法吗?
这是activity(我只展示了它的相关部分):
class MainActivity : AppCompatActivity(), RecyclerAdapter.Callback, androidx.appcompat.widget.SearchView.OnQueryTextListener {
private lateinit var binding: ActivityMainBinding
private val movies = mutableListOf<Movie>()
private lateinit var adapter: RecyclerAdapter
private lateinit var progressBar: ProgressBar
private lateinit var mMoviesViewModel: MoviesViewModel
private val viewModel: MainViewModel by viewModels(
factoryProducer = { MainViewModelFactory() }
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.svSearch.setOnQueryTextListener(this)
//setup progress bar
progressBar = binding.ProgressBar
progressBar.visibility = View.VISIBLE
setObservers()
initRecyclerView()
}
private fun initRecyclerView() {
adapter = RecyclerAdapter(movies)
binding.rvMovies.layoutManager = GridLayoutManager(this, 3)
binding.rvMovies.adapter = adapter
adapter.callback = this
}
//instantiate database for later
val db = Room.databaseBuilder(
this,
MoviesDatabase::class.java, "database-name"
).build()
val dao = db.moviesDao()
//send details of clicked movie to fragment
override fun onMovieClicked(movie: Movie) {
val transaction = supportFragmentManager
val detailFragment = DetailFragment()
val data = Bundle()
//check if movie is already in database
if(dao.movieExists(movie.id)){
//send movie's id to fragment
data.putString("Title", movie.title)
detailFragment.arguments = data
} else {
val title = movie.title
val image = movie.poster
val overview = movie.overview
val language = movie.originalLanguage
val releaseDate = movie.releaseDate
val popularity = movie.popularity
val voteAverage = movie.voteAverage
//create movie object
val movie = Movies(id =0, title, image, overview,
language, popularity, releaseDate, voteAverage
)
//add data to db
mMoviesViewModel.addMovie(movie)
//send movie's id to fragment
data.putString("Title", movie.title)
detailFragment.arguments = data
}
//pass data to fragment
transaction.beginTransaction()
.replace(R.id.frag_container, detailFragment)
.addToBackStack(null)
.commit()
}
}
堆栈跟踪:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.app.challengemovieapp.develop, PID: 13142
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.app.challengemovieapp.develop/com.app.challengemovieapp.ui.MainActivity}: java.lang.IllegalStateException: System services not available to Activities before onCreate()
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3032)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3269)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1960)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7094)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)
Caused by: java.lang.IllegalStateException: System services not available to Activities before onCreate()
at android.app.Activity.getSystemService(Activity.java:6143)
at androidx.room.RoomDatabase$JournalMode.resolve(RoomDatabase.java:663)
at androidx.room.RoomDatabase$Builder.build(RoomDatabase.java:1346)
at com.app.challengemovieapp.ui.MainActivity.<init>(MainActivity.kt:129)
at java.lang.Class.newInstance(Native Method)
at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:69)
at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45)
at android.app.Instrumentation.newActivity(Instrumentation.java:1219)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3020)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3269)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1960)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7094)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)
您需要移动这些行:
val db = Room.databaseBuilder(
this,
MoviesDatabase::class.java, "database-name"
).build()
val dao = db.moviesDao()
Room 需要调用 Context
上的方法,这些方法在您的 MainActivity
实例化时尚未就绪。在 onCreate()
函数 super.onCreate()
之前,您不应该尝试使用 Room。