java - 无法在房间数据库 Android 中插入值
问题描述
我正在尝试插入有关电影的信息,但出现此错误:
java.lang.NullPointerException: Attempt to invoke virtual method 'void kawi15.myapplication.database.DatabaseViewModel.addWatchlistMovie(info.movito.themoviedbapi.model.MovieDb)' on a null object reference
我确定 Movie 不为空,因为我有 Toast 向我显示有关这部电影的信息。
我发现我需要DatabaseViewModel
在我的 OnCreate() 中进行初始化:
databaseViewModel = new ViewModelProvider(this).get(DatabaseViewModel.class);
但我在 OnCreate 和 OnCreateView 以及它的错误中都尝试了这个:
new ViewModelProvider(this)
我尝试将 getContext() 或其他一些东西放在那里,但这里没有任何效果。
这是我的实体类:
@Entity
public class Watchlist {
@PrimaryKey
@ColumnInfo(name = "id")
private int movieId;
@ColumnInfo(name = "movie_title")
private String movieTitle;
@ColumnInfo(name = "poster_path")
private String posterPath;
@ColumnInfo(name = "overview")
private String overview;
@ColumnInfo(name = "release_date")
private String releaseDate;
and getters and setters for all
我的道课:
@Dao
public interface WatchlistDao {
@Query("SELECT * FROM watchlist ORDER BY movie_title ASC")
List<Watchlist> getAll();
@Insert
void addMovie(Watchlist watchlistMovie);
}
视图模型类:
public class DatabaseViewModel extends AndroidViewModel {
private AppDatabase db;
public DatabaseViewModel(@NonNull Application application) {
super(application);
db = AppDatabase.getDatabase(application);
}
public void addWatchlistMovie(MovieDb movieDb){
Watchlist addedMovie = new Watchlist();
addedMovie.setMovieId(movieDb.getId());
addedMovie.setMovieTitle(movieDb.getOriginalTitle());
addedMovie.setOverview(movieDb.getOverview());
addedMovie.setPosterPath(movieDb.getPosterPath());
addedMovie.setReleaseDate(movieDb.getReleaseDate());
db.watchlistDao().addMovie(addedMovie);
}
我从要插入数据库的列表中单击电影的片段类:
public class FragmentOne extends Fragment /*implements CustomAdapter.ListItemClickListener*/{
private static RecyclerView.Adapter adapter;
private RecyclerView.LayoutManager layoutManager;
private DatabaseViewModel databaseViewModel;
private static RecyclerView recyclerView;
private List<MovieDb> data;
//private CustomAdapter.ListItemClickListener mOnClickListener;
public static FragmentOne newInstance() {
FragmentOne fragment = new FragmentOne();
return fragment;
}
/*@Override
public void onListItemClick(int position) {
Toast.makeText(getContext(), data.get(position).getOriginalTitle(), LENGTH_SHORT).show();
}*/
public class MovieTask extends AsyncTask<Void, Void, List<MovieDb>> {
@Override
protected List<MovieDb> doInBackground(Void... voids) {
MovieResultsPage movies = new TmdbApi("f753872c7aa5c000e0f46a4ea6fc49b2").getMovies().getUpcoming("en-US", 1, "US");
List<MovieDb> listMovies = movies.getResults();
return listMovies;
}
@Override
protected void onPostExecute(List<MovieDb> movieDb) {
data = movieDb;
adapter = new CustomAdapter(data);
((CustomAdapter) adapter).setOnMovieDbClicked(movieDb2 -> {
Toast.makeText(getActivity(), movieDb2.getReleaseDate(), LENGTH_SHORT).show();
databaseViewModel.addWatchlistMovie(movieDb2);
});
recyclerView.setAdapter(adapter);
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View returnView = inflater.inflate(R.layout.fragment_one, container, false);
recyclerView = (RecyclerView) returnView.findViewById(R.id.my_recycler_view);
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(getContext()); // ???
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
MovieTask mt = new MovieTask();
mt.execute();
return returnView;
}
}
和我的适配器类,也许不是必需的:
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder>{
private List<MovieDb> dataSet;
private OnMovieDbClicked onMovieDbClicked;
public void setOnMovieDbClicked(OnMovieDbClicked onMovieDbClicked) {
this.onMovieDbClicked = onMovieDbClicked;
}
//final private ListItemClickListener mOnClickListener;
public class MyViewHolder extends RecyclerView.ViewHolder /*implements View.OnClickListener*/{
TextView textViewName;
TextView textViewVersion;
ImageView imageViewIcon;
//private ListItemClickListener mOnClickListener;
public MyViewHolder(View itemView) {
super(itemView);
this.textViewName = (TextView) itemView.findViewById(R.id.text1);
this.textViewVersion = (TextView) itemView.findViewById(R.id.text2);
this.imageViewIcon = (ImageView) itemView.findViewById(R.id.imageView);
itemView.setOnClickListener(view -> {
int pos = getAdapterPosition();
if (onMovieDbClicked != null && pos != RecyclerView.NO_POSITION) {
MovieDb movieDb = dataSet.get(pos);
onMovieDbClicked.movieDbClicked(movieDb);
}
});
//itemView.setOnClickListener(this);
//itemView.setOnClickListener(CustomAdapter.myOnClickListener);
}
/*@Override
public void onClick(View v) {
int position = getAdapterPosition();
mOnClickListener.onListItemClick(position);
}*/
}
public CustomAdapter(List<MovieDb> data /*ListItemClickListener mOnClickListener*/) {
this.dataSet = data;
//this.mOnClickListener = mOnClickListener;
}
public interface OnMovieDbClicked {
void movieDbClicked(MovieDb movieDb);
}
/*public interface ListItemClickListener{
void onListItemClick(int position);
}*/
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.cards_layout, parent, false);
//view.setOnClickListener(FragmentOne.myOnClickListener);
MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
}
@Override
public void onBindViewHolder(final MyViewHolder holder, final int listPosition) {
TextView textViewName = holder.textViewName;
TextView textViewVersion = holder.textViewVersion;
ImageView imageView = holder.imageViewIcon;
Glide.with(imageView).load("https://image.tmdb.org/t/p/w500" + dataSet.get(listPosition).getPosterPath()).into(imageView);
textViewName.setText(dataSet.get(listPosition).getOriginalTitle());
textViewVersion.setText(dataSet.get(listPosition).getReleaseDate());
}
@Override
public int getItemCount() {
if(dataSet == null){
return 0;
}
return dataSet.size();
}
}
解决方案
您还没有初始化您的databaseViewModel
任何地方,因此预计会出现 NPE。确保在访问之前填写该字段MovieTask
推荐阅读
- java - 如果 XML 标签中有 ID,如何匹配它
- python - 已解决 - 如何保存已发送的带有附件的电子邮件
- php - 学习 laravel 并遇到 getURLList() 的问题;
- r - R 最常见的字符串值
- nginx - 如何在 Kubernetes 中将传入有效负载限制增加到 1 MB 以上
- php - DateTime::diff 的意外结果
- angular - Webpack Module Federation 共享单例模块 @angular/common 的 11.xx 版本不满意(需要 ^7.2.0)
- javascript - 组合嵌套函数的更好方法
- mongodb - 如何匹配 substr 并拉取文档?
- android - 任务“:fluttertoast:compileDebugKotlin”执行失败