Reputation: 716
I have this activity in which I have this callback for when an image is clicked. It was working fine but now I added that if it is clicked then it saves the data on the database. The thing is, now I get the system services not available error and I am not sure how to fix it. Any ideas?
This is the activity (I'm only showing the relevant parts of it):
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()
}
}
Stack trace:
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)
Upvotes: 0
Views: 205
Reputation: 1007554
You will need to move these lines:
val db = Room.databaseBuilder(
this,
MoviesDatabase::class.java, "database-name"
).build()
val dao = db.moviesDao()
Room needs to call methods on Context
that are not ready at the point when your MainActivity
is being instantiated. You should not try using Room until after super.onCreate()
of your onCreate()
function.
Upvotes: 1