对于我的应用程序,我使用sqllite数据库制作电影记录应用程序。电影对象具有标题,用户是否已经看过电影的布尔值以及是否在观看列表中显示该电影
我可以将一部电影添加到sqllite数据库,但是当我运行一个搜索查询以返回一个Movie对象列表时,我尝试在Listview中显示结果时尝试获取空指针异常。
这是我的电影对象的变量类型
public class Movie implements Serializable {
private String movieTitle;
private boolean seen; //true if user has seen movie
private boolean addToWatchlist; //if user wants to add movie to watchlist
这是我的表和ts字段
@Override
public void onCreate(SQLiteDatabase db) {
String CREATE_MOVIE_TABLE = "CREATE TABLE " + MOVIE_TABLE + "("
+ KEY_ID + " INTEGER PRIMARY KEY," + KEY_TITLE + " TEXT,"
+ KEY_SEEN + " INT," + KEY_WATCHLIST + " INT " + ")";
db.execSQL(CREATE_MOVIE_TABLE);
}
我的addMovie方法
public void addMovie(Movie m) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_TITLE, m.getmMovieTitle());
if (m.isSeen()) {
values.put(KEY_SEEN, 1);
}
else {values.put(KEY_SEEN,0);}
if (m.isAddWatchlist()) {
values.put(KEY_WATCHLIST, 1);
}
else {values.put(KEY_WATCHLIST,0);}
System.out.println(values.toString());
db.insert(MOVIE_TABLE, null, values);
db.close();
选择查询是我所有问题的根源。甚至在添加已经看过的电影之后导致空列表,其中我设置了看到= 1;
public ArrayList<Movie> getSeenMovies(){
ArrayList<Movie> seenList = new ArrayList<Movie>();
String selectQuery = "SELECT * FROM " + MOVIE_TABLE + " WHERE " + KEY_SEEN + " == " +1;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
if (cursor != null && cursor.moveToFirst()) {
do {
Movie m = new Movie();
m.setMovieTitle(cursor.getString(1));
m.setSeen(true);
m.setAddWatchlist(Integer.parseInt(cursor.getString(3)) == 1);
seenList.add(m);
}
while (cursor.moveToNext());
}
return seenList;
}
当我尝试使用查询结果填充listview时出现NullPointerException,因为我的MovieArrayAdapter类的getCount方法中的movieList.size()表示我的movieList为null
MovieArrayAdapter
public class MovieArrayAdapter extends BaseAdapter {
private Context context;
private ArrayList<Movie> movieList;
//adapter constructor
public MovieArrayAdapter(Context context, ArrayList<Movie> movieList) {
this.context = context;
this.movieList = movieList;
}
//abstract method returns size of movie list
public int getCount() {
return this.movieList.size();
}
//abstract method returns item at input position in list
public Object getItem(int pos){return this.movieList.get(pos);}
// abstract method gets item id at position i
public long getItemId(int pos){return pos;}
public View getView(int position, View convertView, ViewGroup parent){
View v = View.inflate(context, R.layout.movie_list_entry, null);
//finds MovieTitle textview field in the movie_list entry layout file
TextView title = (TextView)v.findViewById(R.id.MovieTitle);
//sets MovieTitle field to title of movie from list
title.setText(movieList.get(position).getmMovieTitle());
return v;}
}
错误:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.indiana.kupshah.movdex, PID: 4754
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.indiana.kupshah.movdex/com.indiana.kupshah.movdex.SeenList}: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference
at com.indiana.kupshah.movdex.MovieArrayAdapter.getCount(MovieArrayAdapter.java:32)
at android.widget.ListView.setAdapter(ListView.java:493)
at com.indiana.kupshah.movdex.SeenList.onCreate(SeenList.java:27)
at android.app.Activity.performCreate(Activity.java:6662)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
DBHandler movdexDB = new DBHandler(this);是添加影片表单的实例变量
单击“添加”按钮时,会将数据添加到数据库
public void onAddButtonClick(View v){
EditText movieTitle = (EditText) findViewById(R.id.TitleText);
CheckBox seen = (CheckBox) findViewById(R.id.SeenCheck);
CheckBox watch = (CheckBox) findViewById(R.id.WatchCheck);
//converts View values to types suitable for Movie class
String addTitle = movieTitle.getText().toString();
Boolean addSeen = seen.isChecked();
Boolean addWatch = watch.isChecked();
Movie movie = new Movie (addTitle,addSeen,addWatch);
movdexDB.addMovie(movie);
}
这是启动SeenList活动的按钮点击
public void onSeenButtonClick(View v){
Intent myIntent = new Intent(AddMovieEntry.this,SeenList.class);
myIntent.putExtra("seen_list", movdexDB.getSeenMovies());
startActivity(myIntent);
}
最后,SeenList onCreate方法
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_seen_list);
//finds list view and populates from movies from the seen list,
//using the layout established in the MovieAdapter arrayadapter class
ListView SeenListView = (ListView) findViewById(R.id.SeenList);
Intent i = getIntent();
ArrayList<Movie> seenList;
//sets the list of seen and watched movies
seenList = (ArrayList<Movie>) i.getSerializableExtra("seenlist_movies");
MovieArrayAdapter myAdapter = new MovieArrayAdapter(this, seenList);
SeenListView.setAdapter(myAdapter);
}
答案 0 :(得分:-1)
看起来你只需要在MovieArrayAdapter中保护对空值的访问:
public int getCount(){
return movieList != null ? movieList.size() : 0;
}