Android搜索查询返回空列表

时间:2017-04-02 00:20:41

标签: java android sql sqlite

对于我的应用程序,我使用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);
}

1 个答案:

答案 0 :(得分:-1)

看起来你只需要在MovieArrayAdapter中保护对空值的访问:

public int getCount(){            
  return movieList != null ? movieList.size() : 0;
}