使用 SQLOpenHelper 抛出错误设置 2 table

Setting up 2 table with SQLOpenHelper throw error

我正在尝试重建我的数据库处理程序,因为我需要使用 2 个表。

我遵循了此处给出的答案:Multiple Table SQLite DB Adapter(s) in Android? 但这给了我以下问题:Attempt to invoke virtual method 'android.database.Cursor android.database.sqlite.SQLiteDatabase.rawQuery(java.lang.String, java.lang.String[])' on a null object reference

我将把我的 DatabaseAdapter 和 DatabaseReminderHandler 放在下面:

数据库适配器:

package avappmobile.mytasks.DBHandlers;

import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

/**
 * Created by Alexandre on 02/03/2015.
 */
public class DatabaseAdapter {

    public static final String DATABASE_NAME = "myTasks";

    public static final int DATABASE_VERSION = 1;

    private static final String TABLE_TASKS = "tasks",
            KEY_TASK_ID = "id",
            KEY_TITLE = "title",
            KEY_YEAR = "year",
            KEY_MONTH = "month",
            KEY_DAY = "day",
            KEY_HOUR = "hour",
            KEY_MINUTE = "minute",
            KEY_DATE = "date",
            KEY_TIME = "time",
            KEY_EVENT_ID = "eventid";

    private static final String TABLE_REMINDERS = "reminders",
            KEY_REM_ID = "id",
            KEY_DESC = "description",
            KEY_ACTIVE = "active",
            KEY_REM_HOUR = "hour",
            KEY_REM_MINUTE = "minute",
            KEY_DURATION = "duration";


    private final Context context;
    private DatabaseHelper DBHelper;
    private SQLiteDatabase db;

    /**
     * Constructor
     * @param ctx
     */
    public DatabaseAdapter(Context ctx)
    {
        this.context = ctx;
        this.DBHelper = new DatabaseHelper(this.context);
    }

    private static class DatabaseHelper extends SQLiteOpenHelper
    {
        DatabaseHelper(Context context)
        {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db)
        {
            db.execSQL("CREATE TABLE " + TABLE_TASKS + "(" + KEY_TASK_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + KEY_TITLE + " TEXT," +
                    KEY_YEAR + " TEXT," + KEY_MONTH + " TEXT," + KEY_DAY + " TEXT," + KEY_HOUR + " TEXT," + KEY_MINUTE + " TEXT," +
                    KEY_DATE + " TEXT," + KEY_TIME + " TEXT," + KEY_EVENT_ID + " TEXT)");

            db.execSQL("CREATE TABLE " + TABLE_REMINDERS + "(" + KEY_REM_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + KEY_DESC + " TEXT," +
                    KEY_ACTIVE + " TEXT," + KEY_REM_HOUR + " TEXT," + KEY_REM_MINUTE + " TEXT," + KEY_DURATION + " TEXT)");
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion,
                              int newVersion)
        {
            // Adding any table mods to this guy here
        }
    }

    /*
     * open the db
     * @return this
     * @throws SQLException
     * return type: DBAdapter
     */
    public DatabaseAdapter open() throws SQLException
    {
        this.db = this.DBHelper.getWritableDatabase();
        return this;
    }

    /**
     * close the db
     * return type: void
     */
    public void close()
    {
        this.DBHelper.close();
    }
}

数据库提醒处理程序:

package avappmobile.mytasks.DBHandlers;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import avappmobile.mytasks.Objects.Reminder;

/**
 * Created by Alexandre on 01/03/2015.
 */
public class DatabaseReminderHandler  {
/*
    private static final int DATABASE_VERSION = 1;

    private static final String DATABASE_NAME = "myTasks",
            TABLE_REMINDERS = "reminders",
            KEY_ID = "id",
            KEY_DESC = "description",
            KEY_ACTIVE = "active",
            KEY_HOUR = "hour",
            KEY_MINUTE = "minute",
            KEY_DURATION = "duration";
*/
    private static final String ID = "id";
    private static final String DESC = "description";
    private static final String ACTIVE = "active";
    private static final String HOUR = "hour";
    private static final String MINUTE = "minute";
    private static final String DURATION = "duration";

    private static final String DATABASE_TABLE = "reminders";

    private DatabaseHelper mDbHelper;
    private SQLiteDatabase mDb;

    private final Context mCtx;

    private static class DatabaseHelper extends SQLiteOpenHelper {

        DatabaseHelper(Context context) {
            super(context, DatabaseAdapter.DATABASE_NAME, null, DatabaseAdapter.DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        }
    }

    public DatabaseReminderHandler(Context context) {
        //super(context, DATABASE_NAME, null, DATABASE_VERSION);
        this.mCtx = context;
    }

    public DatabaseReminderHandler open() throws SQLException {
        this.mDbHelper = new DatabaseHelper(this.mCtx);
        this.mDb = this.mDbHelper.getWritableDatabase();
        return this;
    }

    public void close(){
        this.mDbHelper.close();
    }
/*
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE " + TABLE_REMINDERS + "(" + KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + KEY_DESC + " TEXT," +
                KEY_ACTIVE + " TEXT," + KEY_HOUR + " TEXT," + KEY_MINUTE + " TEXT," + KEY_DURATION + " TEXT)");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_REMINDERS);

        onCreate(db);
    }
*/
    public void createReminder(Reminder reminder) {

        ContentValues values = new ContentValues();

        values.put(DESC, reminder.getDescription());
        values.put(ACTIVE, reminder.getActive());
        values.put(HOUR, reminder.getHour());
        values.put(MINUTE, reminder.getMinute());
        values.put(DURATION, reminder.getDuration());

        this.mDb.insert(DATABASE_TABLE, null, values);
    }

    public Reminder getReminder(int id) {
        Cursor cursor = this.mDb.query(DATABASE_TABLE, new String[] { ID, DESC, ACTIVE, HOUR, MINUTE, DURATION }, ID + "=?", new String[] { String.valueOf(id) }, null, null, null, null );

        if (cursor != null)
            cursor.moveToFirst();

        Reminder reminder = new Reminder(Integer.parseInt(cursor.getString(0)), cursor.getString(1), Boolean.valueOf(cursor.getString(2)), Integer.parseInt(cursor.getString(3)),
                Integer.parseInt(cursor.getString(4)), Integer.parseInt(cursor.getString(5)));

        return reminder;
    }

    public Reminder getReminder(String description) {
        Cursor cursor = this.mDb.query(DATABASE_TABLE, new String[] { ID, DESC, ACTIVE, HOUR, MINUTE, DURATION }, DESC + "=?", new String[] { description }, null, null, null, null );

        if (cursor != null)
            cursor.moveToFirst();

        Reminder reminder = new Reminder(Integer.parseInt(cursor.getString(0)), cursor.getString(1), Boolean.valueOf(cursor.getString(2)), Integer.parseInt(cursor.getString(3)),
                Integer.parseInt(cursor.getString(4)), Integer.parseInt(cursor.getString(5)));

        return reminder;
    }

    public int getRemindersCount() {
        Cursor cursor = this.mDb.rawQuery("SELECT * FROM " + DATABASE_TABLE, null);
        int count = cursor.getCount();

        return count;
    }

    public int getActiveReminders() {
        Cursor cursor = this.mDb.rawQuery("SELECT * FROM " + DATABASE_TABLE + "WHERE active = 'true'", null);
        int count = cursor.getCount();

        return count;
    }

    public List<Reminder> getActiveListReminders() {
        List<Reminder> reminders = new ArrayList<Reminder>();

        Cursor cursor = this.mDb.rawQuery("SELECT * FROM " + DATABASE_TABLE  + "WHERE active = 'true'", null);

        if (cursor.moveToFirst()) {
            do {
                reminders.add(new Reminder(Integer.parseInt(cursor.getString(0)), cursor.getString(1), Boolean.valueOf(cursor.getString(2)), Integer.parseInt(cursor.getString(3)),
                        Integer.parseInt(cursor.getString(4)), Integer.parseInt(cursor.getString(5))));
            }
            while (cursor.moveToNext());
        }

        return reminders;
    }

    public int updateReminder(Reminder reminder) {
        ContentValues values = new ContentValues();

        values.put(DESC, reminder.getDescription());
        values.put(ACTIVE, reminder.getActive());
        values.put(HOUR, reminder.getHour());
        values.put(MINUTE, reminder.getMinute());
        values.put(DURATION, reminder.getDuration());

        int rowsAffected = this.mDb.update(DATABASE_TABLE, values, ID + "=" + reminder.getId(), null);

        return rowsAffected;
    }

    public List<Reminder> getAllReminders() {
        List<Reminder> reminders = new ArrayList<Reminder>();

        Cursor cursor = this.mDb.rawQuery("SELECT * FROM " + DATABASE_TABLE, null);

        if (cursor.moveToFirst()) {
            do {
                reminders.add(new Reminder(Integer.parseInt(cursor.getString(0)), cursor.getString(1), Boolean.valueOf(cursor.getString(2)), Integer.parseInt(cursor.getString(3)),
                        Integer.parseInt(cursor.getString(4)), Integer.parseInt(cursor.getString(5))));
            }
            while (cursor.moveToNext());
        }

        return reminders;
    }

    public void initReminders(Context context){
        int count = this.getRemindersCount();

        if(count == 0){

            // Create the 3 reminders
            Reminder rem1 = new Reminder(count, "REMINDER_1", true, 0, 5, 5);
            Reminder rem2 = new Reminder(count + 1, "REMINDER_2", true, 1, 0, 60);
            Reminder rem3 = new Reminder(count + 2, "REMINDER_3", true, 24, 0, 1440);

            this.createReminder(rem1);
            this.createReminder(rem2);
            this.createReminder(rem3);
        }
    }
}

我还把我的 mainActivity (HomePage.class) 放在我初始化变量并开始使用它们的地方:

首页(只是一部分,不是全部):

public class HomePage extends ActionBarActivity {

    final Context context = this;
    private static final int EDIT = 0, DELETE = 1;

    DatabaseTaskHandler dbHandler;
    DatabaseReminderHandler dbRemHandler;
    ListView taskListView;
    ArrayAdapter<Task> taskAdapter;

    int longClickedItemIndex;

    List<Task> Tasks = new ArrayList<Task>();

    FragmentManager fm = getSupportFragmentManager();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home_page);

        dbHandler = new DatabaseTaskHandler(this);
        dbRemHandler = new DatabaseReminderHandler(this);
        dbRemHandler.initReminders(getApplicationContext());
        taskListView = (ListView) findViewById(R.id.listViewTasks);

        // The following piece of code allows to empty database before testing when reinstalling the app for test.
        //getApplicationContext().deleteDatabase("myTasks");

        registerForContextMenu(taskListView);

        taskListView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                return false;
            }
        });

        taskListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                longClickedItemIndex = position;
                return false;
            }
        });

        if (dbHandler.getTasksCount() != 0)
            Tasks.addAll(dbHandler.getAllTasks());

        populateTasksList();
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_home_page, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
/*
        switch (id){
            case R.id.action_settings:
                Intent intent = new Intent(this, RemindersSettings.class);
                startActivity(intent);
                break;
            default:
                return super.onOptionsItemSelected(item);
        }
*/
        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);

        //return true;
    }

    private class TaskListAdapter extends ArrayAdapter<Task> {

        public TaskListAdapter(){
            super(HomePage.this, R.layout.tasklist_item, Tasks);
        }

        @Override
        public View getView(int position, View view, ViewGroup parent){
            if (view == null) {
                view = getLayoutInflater().inflate(R.layout.tasklist_item, parent, false);
            }

            Task currentTask = Tasks.get(position);

            TextView taskListName = (TextView) view.findViewById(R.id.txtTaskListName);
            taskListName.setText(currentTask.getTitle());
            TextView taskListDate = (TextView) view.findViewById(R.id.txtTaskListDate);
            taskListDate.setText(currentTask.getDate());
            TextView taskListTime = (TextView) view.findViewById(R.id.txtTaskListTime);
            taskListTime.setText(currentTask.getTime());
            ImageButton deleteButton = (ImageButton) view.findViewById(R.id.btnDelete);
            deleteButton.setTag(R.id.taskId,currentTask.getId());
            deleteButton.setTag(R.id.position,position);
            Button editButton = (Button) view.findViewById(R.id.btnEdit);
            editButton.setTag(R.id.taskId, currentTask.getId());
            editButton.setTag(R.id.position, position);

            return view;
        }
    }

提前致谢。 亚历克斯

在您的 MainActivity 中,您忘记在 class DatabaseReminderHandler 上调用方法 open()。

dbRemHandler = new DatabaseReminderHandler(this);
dbRemHandler.initReminders(getApplicationContext());
dbRemHandler.open();

终于知道怎么解决了

我在设置其中一些时到处都遗漏了不同的 db.open,例如我的主页:

我正在设置:

dbHandler = new DatabaseTaskHandler(this);
dbRemHandler = new DatabaseReminderHandler(this);

我还要补充:

try {
    dbHandler.open();
} catch (SQLException e) {
            e.printStackTrace();
}
try {
    dbRemHandler.open();
} catch (SQLException e) {
    e.printStackTrace();
}

现在工作正常。

亚历克斯