Пользовательский SimpleCursorAdapter, запрос к базе данных и исключение NullPointerException - PullRequest
3 голосов
/ 19 апреля 2011

Я пытаюсь сделать ListView заполненным из базы данных и приправить каждую строку необычной кнопкой удаления. Поэтому я составил список Activity и пользовательский SimpleCursorAdapter.

Это основная активность ListView:

    public class EditEntries extends ListActivity {
    Cursor cursor;
    DBAdapter db = new DBAdapter(this);
    private static String[] FROM = { _ID, SCORE_COLUMN,
            "date(time, 'localtime')", };
    private static int[] TO = { R.id.rowid, R.id.title, R.id.time, };

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.entries_list);
        try {
            cursor = getEvents();
            showEvents(cursor);
        } finally {
            db.close();
        }
    }

    private void showEvents(Cursor cursor) {
        // Set up data binding
        SMSimpleCursorAdapter adapter = new SMSimpleCursorAdapter(this,
                R.layout.entries_list_item, cursor, FROM, TO);
        setListAdapter(adapter);

    }

    private Cursor getEvents() {
        db.open();
        cursor = db.getAllScores();
        startManagingCursor(cursor);
        return cursor;
    }

    void delRow() {        // this is method for deleting row by _id
        db.open();
        db.deleteScore(3); // here will be TAG with _id from adapter,
        db.close();        // for now I just use hardcoded _id
    }

}

А это пользовательский SimpleCursorAdapter:

    public class SMSimpleCursorAdapter extends SimpleCursorAdapter{

    Cursor c;
    Context context;
    Activity activity;

    public SMSimpleCursorAdapter(Context context, int layout, Cursor c,
            String[] from, int[] to) {
        super(context, layout, c, from, to);

        this.c = c;
        this.context=context;
        this.activity=(Activity) context;

    }
    EditEntries dbDel = new EditEntries(); //from previous code sample

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if(convertView == null)
            convertView = View.inflate(context, R.layout.entries_list_item, null);
        View row = convertView;

        c.moveToPosition(position);

        TextView score = (TextView) convertView.findViewById(R.id.title);
        TextView time = (TextView) convertView.findViewById(R.id.time);
        TextView id = (TextView) convertView.findViewById(R.id.rowid);

        id.setText(c.getString(0));
        time.setText(c.getString(2));
        score.setText(c.getString(1));

        String daTag = c.getString(1);

        ImageButton delButton = (ImageButton) convertView.findViewById(R.id.delButton);
        delButton.setFocusable(true);
        delButton.setClickable(true);
        //delButton.setTag(daTag);
        delButton.setOnClickListener(new OnClickListener() { //Click listener fro delete button
             @Override
             public void onClick(View view) {
                 dbDel.delRow(); //this is "delete row" method from previos code                    sample
             }
             });

        return(row);
    }

}

И все эти вещи дают мне NullPointerException, когда я нажимаю кнопку удаления. Я новичок в Android, и предположим, что я пропустил что-то очевидное.

LogCat:

ОШИБКА / AndroidRuntime (14027): ИСКЛЮЧИТЕЛЬНОЕ ИСКЛЮЧЕНИЕ: main

ОШИБКА / AndroidRuntime (14027): java.lang.NullPointerException

ОШИБКА / AndroidRuntime (14027): в android.content.ContextWrapper.openOrCreateDatabase (ContextWrapper.java:203)

ОШИБКА / AndroidRuntime (14027): в android.database.sqlite.SQLiteOpenHelper.getWritableDatabase (SQLiteOpenHelper.java:98)

ОШИБКА / AndroidRuntime (14027): в пространстве имен. DBAdapter.open (DBAdapter.java:66)

ОШИБКА / AndroidRuntime (14027): в пространстве имен.EditEntries.delRow (EditEntries.java:50)

ОШИБКА / AndroidRuntime (14027): в пространстве имен.SMSimpleCursorAdapter $ 1.onClick (SMSimpleCursorAdapter.java:64)

ОШИБКА / AndroidRuntime (14027): на android.view.View.performClick (View.java:2414)

ОШИБКА / AndroidRuntime (14027): на android.view.View $ PerformClick.run (View.java:8838)

ОШИБКА / AndroidRuntime (14027): на android.os.Handler.handleCallback (Handler.java:587)

ОШИБКА / AndroidRuntime (14027): на android.os.Handler.dispatchMessage (Handler.java:92)

ОШИБКА / AndroidRuntime (14027): на android.os.Looper.loop (Looper.java:123)

ОШИБКА / AndroidRuntime (14027): на android.app.ActivityThread.main (ActivityThread.java:4680)

ОШИБКА / AndroidRuntime (14027): на java.lang.reflect.Method.invokeNative (собственный метод)

ОШИБКА / AndroidRuntime (14027): в java.lang.reflect.Method.invoke (Method.java:521)

ОШИБКА / AndroidRuntime (14027): на com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:858)

ОШИБКА / AndroidRuntime (14027): на com.android.internal.os.ZygoteInit.main (ZygoteInit.java:616)

ОШИБКА / AndroidRuntime (14027): в dalvik.system.NativeStart.main (собственный метод)

1 Ответ

7 голосов
/ 19 апреля 2011

Проблема в вашем коде SMSimpleCursorAdapter:

EditEntries dbDel = new EditEntries(); //from previous code sample

Вы создаете новый объект, но это не будет управляемое действие (например, метод onCreate не будет вызываться). Вероятно, NPE приходит из вашего DBAdapter, когда вы пытаетесь создать его во второй раз (из вашего адаптера).

Быстрое исправление:

EditEntries dbDel; //from previous code sample
public SMSimpleCursorAdapter(Context context, int layout, Cursor c,
        String[] from, int[] to) {
    super(context, layout, c, from, to);

    this.c = c;
    this.context = context;
    this.activity = (Activity) context;
    this.dbDel = (EditEntries) context;
}

Если вы не хотите просто быстрое исправление, лучшим решением будет следующее:

  1. Переместите метод delRow, getEvents в свой класс DBAdapter
  2. Измените конструктор вашего SMSimpleCursorAdapter, чтобы он передавался в классе DBAdapter (создан в вашей ListActivity).
...