I am trying to fetch data by using retrofit with MVVM Architecture. When I wanted to print the data on console, it works.
But when I wanna use them on the RecyclerView
, I get this error:
E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.movieapp, PID: 4275 android.os.NetworkOnMainThreadException.
Here is my codes:
MovieRepository
public class MovieRepository {
private static MovieService movieService;
private final MutableLiveData<List<Movie>> listOfPopularMovie ;
private static MovieRepository newsRepository;
public static MovieRepository getInstance(){
if(newsRepository == null){
newsRepository=new MovieRepository();
}
return newsRepository;
}
public MovieRepository(){
movieService= RetrofitService.getMovieService();
listOfPopularMovie=new MutableLiveData<>();
}
public MutableLiveData<List<Movie>> getListOfPopularMovie(String key,int page) {
Call<MovieResponse> popularMovies= movieService.getPopularMovie(key,page);
popularMovies.enqueue(new Callback<MovieResponse>() {
@Override
public void onResponse(Call<MovieResponse> call, Response<MovieResponse> response) {
listOfPopularMovie.setValue(response.body().getResults());
}
@Override
public void onFailure(Call<MovieResponse> call, Throwable t) {
listOfPopularMovie.postValue(null);
}
});
return listOfPopularMovie;
}
MainViewModel
public class MainViewModel extends AndroidViewModel {
private MutableLiveData<List<Movie>> listOfPopularMovies = new MutableLiveData<>();
private MovieRepository movieRepository;
public MainViewModel(@NonNull Application application) {
super(application);
movieRepository = MovieRepository.getInstance();
}
public MutableLiveData<List<Movie>> getListOfPopularMovies(String key, int page) {
listOfPopularMovies=movieRepository.getListOfPopularMovie(key,page);
return listOfPopularMovies;
}
MovieAdapter
public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.MovieViewHolder> {
private List<Movie> movies;
private Context mContext;
public MovieAdapter(Context context){
mContext=context;
}
@NonNull
@Override
public MovieViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view= LayoutInflater.from(mContext).inflate(R.layout.item_view,parent,false);
return new MovieViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MovieViewHolder holder, int position) {
Movie movie=movies.get(position);
String currentTitle=movie.getTitle();
String imageUrl="https://image.tmdb.org/t/p/original";
imageUrl +=movie.getBackdrop_path();
try {
URL url=new URL(imageUrl);
Bitmap bmp=BitmapFactory.decodeStream(url.openConnection().getInputStream());
Drawable drawable=new BitmapDrawable(mContext.getResources(),bmp);
holder.image.setBackground(drawable);
holder.title.setText(currentTitle);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public int getItemCount() {
if(movies == null)
return 0;
return movies.size();
}
public void setMovie(List<Movie> taskEntries) {
movies = taskEntries;
notifyDataSetChanged();
}
class MovieViewHolder extends RecyclerView.ViewHolder {
LinearLayout image;
TextView title;
public MovieViewHolder(@NonNull View itemView) {
super(itemView);
image=itemView.findViewById(R.id.movie_image);
title=itemView.findViewById(R.id.movie_title);
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
MovieAdapter movieAdapter;
RecyclerView recyclerView;
MainViewModel mainViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView= findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
movieAdapter= new MovieAdapter(this);
recyclerView.setAdapter(movieAdapter);
DividerItemDecoration decoration = new DividerItemDecoration(getApplicationContext(), VERTICAL);
recyclerView.addItemDecoration(decoration);
mainViewModel= new ViewModelProvider(this,ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication())).get(MainViewModel.class);
mainViewModel.getListOfPopularMovies("9e2629973011b0744ce3b589dff1fb32",1).observe(this, new Observer<List<Movie>>() {
@Override
public void onChanged(List<Movie> movies) {
movieAdapter.setMovie(movies);
}
});
}