i'm trying to implement a movie app that allows brows movies and checkout the ratings on them... and i got a problem when i tried to implement a MVVM model with my MovieListViewModel where the debugger is telling me that i cannot create an instance of this class (MovieListViewModel).
what i did about that is i tried to follow some tutorials and i looked for all the questions about viewmodel in this site they would usually say that i should have my viewmodel's constructor as a public constructor or there is some other problem in the constructor (parameters and things like that ) but i'm sure that i followed the guideline regarding the constructor
(i tried following this tutorial to implement the first part of my application ) https://medium.com/@eladb4382/paging-library-viewmodel-livedata-room-and-retrofit-66bf6a0eef9d i did basically the same code but i had the error where he didn't ...
this is my list view model class :
public class MovieListViewModel extends AndroidViewModel {
private MovieRepository repository;
public MovieListViewModel(@NonNull Application application) {
super(application);
repository = MovieRepository.getInstance(application);
}
public LiveData<PagedList<Movie>> getMovies() {
return repository.getMovies();
}
public LiveData<NetworkState> getNetworkState() {
return repository.getNetworkState();
}}
and here where is the problem happening :
public class MovieListFragment extends Fragment implements OnMovieItemClicked {
private final String TAG = MovieListFragment.class.getSimpleName() ;
protected MovieListViewModel viewmodel ;
private MovieDetailsViewModel movieDetailsViewModel ;
protected RecyclerView recyclerView ;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.movie_list_fragment , container , false );
recyclerView = view.findViewById(R.id.moviesRecyclerView);
recyclerView.setLayoutManager(new GridLayoutManager(getContext(),3));
Log.d(TAG , "creating viewmodel ..." );
viewmodel = ViewModelProviders.of(getActivity()).get(MovieListViewModel.class);
observersRegisters() ;
return view;
}
private void observersRegisters() {
final MovieAdapter adapter = new MovieAdapter(this);
viewmodel.getMovies().observe(this , adapter ::submitList);
viewmodel.getNetworkState().observe(this,networkState ->{
adapter.setNetworkState(networkState);
});
recyclerView.setAdapter(adapter);
movieDetailsViewModel = ViewModelProviders.of(getActivity()).get(MovieDetailsViewModel.class);
}
(this is not the whole fragment class it's just the part where the error is happening)
and the activity where i call this fragment is here ::
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName() ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(findViewById(R.id.fragmentsContainer)!= null) {
if(savedInstanceState != null ){
return ;
}
MovieListFragment listFragment = new MovieListFragment() ;
listFragment.setArguments(getIntent().getExtras());
getSupportFragmentManager().beginTransaction().add(R.id.fragmentsContainer,listFragment).commit();
}}
also i uploaded the whole project on GitHub in case anyone would like to checkout the problem :
https://github.com/TheDeathLorD/MovieApp
here is the error I'm getting on run time :
E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.movieapp2, PID: 4935 java.lang.RuntimeException: Cannot create an instance of class com.example.movieapp2.ui.viewmodel.MovieListViewModel at android.arch.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:207) at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:134) at android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:102) at com.example.movieapp2.ui.view.MovieListFragment.onCreateView(MovieListFragment.java:40)
In your case, you should see the whole logs, I tried your code, and there is more info below the error you post:
Caused by: java.lang.IllegalArgumentException: baseUrl must end in /: http://api.themoviedb.org/3/movie/popular
at retrofit2.Retrofit$Builder.baseUrl(Retrofit.java:515)
at retrofit2.Retrofit$Builder.baseUrl(Retrofit.java:458)
at com.example.movieapp2.repository.network.api.MovieAPIClient.getInstance(MovieAPIClient.java:27)
at com.example.movieapp2.repository.network.paging.NetMoviePageKeyedDataSource.<init>(NetMoviePageKeyedDataSource.java:32)
at com.example.movieapp2.repository.network.paging.NetMovieDataSourceFactory.<init>(NetMovieDataSourceFactory.java:18)
at com.example.movieapp2.repository.MovieRepository.<init>(MovieRepository.java:27)
at com.example.movieapp2.repository.MovieRepository.getInstance(MovieRepository.java:56)
which means you should add a /
after your baseUrl
And then you will see another crash says Missing either @GET URL or @Url parameter
. It because @GET URL is blank in MovieAPIInterface.getMovies
, I recommend you change the baseUrl to http://api.themoviedb.org/3/movie
and put popular
into @GET annotation