【问题标题】:Viewmodel cannot create an instance of class Android Java MVVMViewmodel 无法创建类 Android Java MVVM 的实例
【发布时间】:2020-01-01 22:04:58
【问题描述】:

我正在尝试实现一个电影应用程序,该应用程序允许浏览电影并检查它们的评级...当我尝试使用我的 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/AndroidRuntime: 致命异常: main 进程: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)

【问题讨论】:

    标签: java android mvvm viewmodel android-components


    【解决方案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注解中

    【讨论】:

      【解决方案2】:

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

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

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

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

      通过传递this 这是您的片段,您的问题可能会得到解决。

      【讨论】:

        【解决方案3】:

        在我的例子中,我在 ViewModel 类中传递了参数! 我删除了它并解决了我的问题。

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

        只需删除 arg,因为我不需要那个 arg 并且是多余的:

        class MainViewModel() : ViewModel() {
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-07-17
          • 1970-01-01
          • 2021-11-28
          • 2017-12-13
          • 1970-01-01
          相关资源
          最近更新 更多