Viewmodel无法创建类Android Java MVVM的实例

时间:2019-08-28 16:14:30

标签: java android mvvm viewmodel android-components

我正在尝试实现一个允许浏览电影并检查其收视率的电影应用程序...当我尝试用我的MovieListViewModel实现MVVM模型时,调试器告诉我我无法解决这个问题创建此类的实例(MovieListViewModel)。

我所做的是尝试遵循一些教程,并且在该站点中查找了有关viewmodel的所有问题,他们通常会说我应该将viewmodel的构造函数作为公共构造函数使用,否则构造函数(参数和类似的东西),但是我确定我遵循了有关构造函数的准则

(我尝试按照本教程实施应用程序的第一部分) https://medium.com/@eladb4382/paging-library-viewmodel-livedata-room-and-retrofit-66bf6a0eef9d 我基本上执行了相同的代码,但是我有一个错误,他没有...

这是我的列表视图模型类:

公共类MovieListViewModel扩展了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();
}}

以及这里发生的问题:

公共类MovieListFragment扩展了Fragment实现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);
}

(这不是整个片段类,而只是发生错误的部分)

和我称之为此片段的活动在这里::

公共类MainActivity扩展了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();
    }}

我还把整个项目都上传到了GitHub,以防万一有人想结帐:

https://github.com/TheDeathLorD/MovieApp

这是我在运行时遇到的错误:

E / Android运行时:致命异常:主要     流程:com.example.movi​​eapp2,PID:4935     java.lang.RuntimeException:无法创建com.example.movi​​eapp2.ui.viewmodel.MovieListViewModel类的实例         在android.arch.lifecycle.ViewModelProvider $ AndroidViewModelFactory.create(ViewModelProvider.java:207)         在android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:134)         在android.arch.lifecycle.ViewModelProvider.get(ViewModelProvider.java:102)         在com.example.movi​​eapp2.ui.view.MovieListFragment.onCreateView(MovieListFragment.java:40)

3 个答案:

答案 0 :(得分:1)

在您的情况下,您应该看到整个日志,我尝试了您的代码,并且在您发布的错误下方有更多信息:

     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)

这意味着您应该在baseUrl之后添加一个/

然后您将看到另一个崩溃提示Missing either @GET URL or @Url parameter。因为@GET URL在MovieAPIInterface.getMovies中为空,所以我建议您将baseUrl更改为http://api.themoviedb.org/3/movie并将popular放入@GET注释

答案 1 :(得分:1)

您正在使用此行代码在片段中填充视图模型

viewmodel = ViewModelProviders.of(getActivity()).get(MovieListViewModel.class);

由于getActivity()对我来说似乎有点不对劲。您需要片段而不是活动的视图模型,所以请尝试

viewmodel = ViewModelProviders.of(this).get(MovieListViewModel.class);

通过传递this这是您的片段,就可以解决问题。

答案 2 :(得分:0)

在我的情况下,我在ViewModel类中传递了args! 我将其删除并解决了问题。

class MainViewModel(private val repository: Repository) : ViewModel() {

只需删除arg,因为我不需要那个arg,而且很多余:

class MainViewModel() : ViewModel() {