I'm building an app using Room Database. In my DetailActivity i've set up a floating action button to mark a movie as favorite. When i click on the fab the app crashes. I provide the method in which i'm having the error.
public void click (){
if (isClicked) {
MoviesExecutor.getInstance().diskIO().execute(new Runnable() {
@Override
public void run() {
mDb.moviesDao().removeMovie(movies.getMovieId());
favoriteFab.setImageResource(R.drawable.heart_favorite_border_black);
}
});
isClicked = false;
} else {MoviesExecutor.getInstance().diskIO().execute(new Runnable() {
@Override
public void run() {
mDb.moviesDao().addMovie(movies);
favoriteFab.setImageResource(R.drawable.heart_favorite_black);
}
});
Toast.makeText(this, "added", Toast.LENGTH_LONG).show();
isClicked = true;
}
LOGS:
02-13 15:30:55.294 21789-21880/? E/AndroidRuntime: FATAL EXCEPTION: pool-2-thread-1
Process: com.example.android.popularmovies2, PID: 21789
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6556)
at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:942)
at android.view.ViewGroup.invalidateChild(ViewGroup.java:5082)
at android.view.View.invalidateInternal(View.java:12758)
at android.view.View.invalidate(View.java:12722)
at android.view.View.invalidate(View.java:12706)
at android.widget.ImageView.setImageDrawable(ImageView.java:479)
at android.support.design.widget.FloatingActionButton.setImageDrawable(FloatingActionButton.java:483)
at android.support.v7.widget.AppCompatImageHelper.setImageResource(AppCompatImageHelper.java:90)
at android.support.design.widget.FloatingActionButton.setImageResource(FloatingActionButton.java:478)
at com.example.android.popularmovies2.DetailActivity$4.run(DetailActivity.java:152)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
The error message is very much self-explanatory, DB operations are almost guaranteed to succeed so you can just move this line:favoriteFab.setImageResource(R.drawable.heart_favorite_border_black);
out of the runnable.
So your code will be something like:
public void click (){
if (isClicked) {
MoviesExecutor.getInstance().diskIO().execute(new Runnable() {
@Override
public void run() {
mDb.moviesDao().removeMovie(movies.getMovieId());
}
});
favoriteFab.setImageResource(R.drawable.heart_favorite_border_black);
isClicked = false;
} else {MoviesExecutor.getInstance().diskIO().execute(new Runnable() {
@Override
public void run() {
mDb.moviesDao().addMovie(movies);
}
});
favoriteFab.setImageResource(R.drawable.heart_favorite_black);
Toast.makeText(this, "added", Toast.LENGTH_LONG).show();
isClicked = true;
}