Hey. I'm new to programming, trying to make a simple reminder application. I was stuck at work with a loader when working with a database. Specifically, the application, when launched, throws a NullPointerException in the onLoadFinished () method.
If you comment out the line swapCursor , then the problem disappears. please what is the problem. This is my main activity with the ReminderListActivity reminder list in which the error occurs. Many thanks to all for the help.
public class ReminderListActivity extends ListActivity implements LoaderManager.LoaderCallbacks <Cursor> { private static final int ACTIVITY_CREATE = 0; private static final int ACTIVITY_EDIT = 1; private ReminderDbAdapter mDbHelper; private ListView remindersList; SimpleCursorAdapter reminders; private static final String TAG = "MyActivity"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.reminder_list); // открываем подключение к БД mDbHelper = new ReminderDbAdapter(this); mDbHelper.open(); fillData(); registerForContextMenu(getListView()); } // заполняем список задач private void fillData() { // формируем столбцы сопоставления String[] from = new String[]{ReminderDbAdapter.KEY_TITLE,}; int[] to = new int[]{R.id.text1}; //создаем адаптер курсора и настраиваем список SimpleCursorAdapter reminders = new SimpleCursorAdapter(this, R.layout.reminder_row, null, from, to, 0); remindersList = (ListView) findViewById(android.R.id.list); remindersList.setAdapter(reminders); // создаем лоадер для чтения данных getLoaderManager().initLoader(0, null, this); } @Override protected void onListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l, v, position, id); super.onListItemClick(l, v, position, id); Intent i = new Intent(this, ReminderEditActivity.class); i.putExtra(ReminderDbAdapter.KEY_TITLE, id); startActivityForResult(i, ACTIVITY_EDIT); } // ContextMenu @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); MenuInflater mi = getMenuInflater(); mi.inflate(R.menu.list_menu_item_longpress, menu); } //Menu @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); MenuInflater mi = getMenuInflater(); mi.inflate(R.menu.list_menu, menu); return true; } //Choose Menu Item @Override public boolean onMenuItemSelected(int featureId, MenuItem item) { switch (item.getItemId()) { case R.id.menu_insert: createReminder(); return true; } return super.onMenuItemSelected(featureId, item); } private void createReminder() { Intent i = new Intent(this, ReminderEditActivity.class); startActivityForResult(i, ACTIVITY_CREATE); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); getLoaderManager().getLoader(0).forceLoad(); } //Choose delete item @Override public boolean onContextItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menu_delete: AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); mDbHelper.deleteReminder(info.id); return true; } return super.onContextItemSelected(item); } @Override public Loader<Cursor> onCreateLoader(int id, Bundle bndl) { return new MyCursorLoader(this, mDbHelper); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { reminders.swapCursor(cursor); } @Override public void onLoaderReset(Loader<Cursor> loader) { } static class MyCursorLoader extends CursorLoader { ReminderDbAdapter mDbHelper; public MyCursorLoader(Context context, ReminderDbAdapter mDbHelper) { super(context); this.mDbHelper = mDbHelper; } @Override public Cursor loadInBackground() { Cursor cursor = mDbHelper.fetchAllReminders(); return cursor; } } }
Here are the activities of the ReminderDbAdapter database adapter.
public class ReminderDbAdapter { private static final String DATABASE_NAME = "data"; private static final String DATABASE_TABLE = "reminders"; private static final int DATABASE_VERSION = 1; public static final String KEY_TITLE = "title"; public static final String KEY_BODY = "body"; public static final String KEY_DATE_TIME = "reminder_date_time"; public static final String KEY_ROWID = "_id"; private DatabaseHelper mDbHelper; private SQLiteDatabase mDb; //data base scenario private static final String DATABASE_CREATE = "create table " + DATABASE_TABLE + " (" + KEY_ROWID + " integer primary key autoincrement, " + KEY_TITLE + " text not null, " + KEY_BODY + " text not null, " + KEY_DATE_TIME + " text not null);"; private Context mCtx; public ReminderDbAdapter(Context ctx) { this.mCtx = ctx; } //Data base creation public ReminderDbAdapter open() throws android.database.SQLException { mDbHelper = new DatabaseHelper(mCtx); mDb = mDbHelper.getWritableDatabase(); return this; } public long createReminder(String title, String body, String reminderDateTime) { ContentValues initialValues = new ContentValues(); initialValues.put(KEY_TITLE, title); initialValues.put(KEY_BODY, body); initialValues.put(KEY_DATE_TIME, reminderDateTime); return mDb.insert(DATABASE_TABLE, null, initialValues); } public boolean deleteReminder(long rowId) { return mDb.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0; } public Cursor fetchAllReminders() { return mDb.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_TITLE, KEY_BODY, KEY_DATE_TIME}, null, null, null, null, null); } public Cursor fetchReminder(long rowId) throws SQLException { Cursor mCursor = mDb.query(true, DATABASE_TABLE, new String[] {KEY_ROWID, KEY_TITLE, KEY_BODY, KEY_DATE_TIME}, KEY_ROWID + "=" + rowId, null,null, null, null, null); if (mCursor != null) { mCursor.moveToFirst(); } return mCursor; } public boolean updateReminder(long rowId, String title, String body, String reminderDateTime) { ContentValues args = new ContentValues(); args.put(KEY_TITLE, title); args.put(KEY_BODY, body); args.put(KEY_DATE_TIME, reminderDateTime); return mDb.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0; } private static class DatabaseHelper extends SQLiteOpenHelper { DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(DATABASE_CREATE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } } //close data base public void close() { mDbHelper.close(); } Well, on the safe side, the text of the logs.
java.lang.NullPointerException at com.dummies.android.taskreminder.ReminderListActivity.onLoadFinished(ReminderListActivity.java:143) at com.dummies.android.taskreminder.ReminderListActivity.onLoadFinished(ReminderListActivity.java:22) at android.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:483) at android.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManager.java:451) at android.content.Loader.deliverResult(Loader.java:143) at android.content.CursorLoader.deliverResult(CursorLoader.java:113) at android.content.CursorLoader.deliverResult(CursorLoader.java:43) at android.content.AsyncTaskLoader.dispatchOnLoadComplete(AsyncTaskLoader.java:254) at android.content.AsyncTaskLoader$LoadTask.onPostExecute(AsyncTaskLoader.java:91) at android.os.AsyncTask.finish(AsyncTask.java:631) at android.os.AsyncTask.access$600(AsyncTask.java:177) at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:5041) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) at dalvik.system.NativeStart.main(Native Method)