0

我正在使用带有扩展 SimpleCursorAdapter 的自定义适配器的光标:

public class ListWordAdapter extends SimpleCursorAdapter {

    private LayoutInflater inflater;
    private Cursor mCursor;
    private int mLayout;
    private String[] from;
    private int[] to;

    public ListWordAdapter(Context context, int layout, Cursor c,
            String[] from, int[] to, int flags) {

        super(context, layout, c, from, to, flags);
        this.mCursor = c;
        this.inflater = LayoutInflater.from(context);
        this.mLayout = layout;
        this.from = from;
        this.to = to;

    }

    private static class ViewHolder {
        //public ImageView img;
        public TextView name;
        public TextView type;
        public TextView translate;

    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        if (mCursor.moveToPosition(position)) {
            ViewHolder holder;

            if (convertView == null) {
                convertView = inflater.inflate(mLayout, null);
                holder = new ViewHolder();
                // holder.img = (ImageView) convertView.findViewById(R.id.img_row);
                holder.name = (TextView) convertView.findViewById(to[0]);
                holder.type = (TextView) convertView.findViewById(to[1]);
                holder.translate = (TextView) convertView.findViewById(to[2]);

                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }

            holder.name.setText(mCursor.getString(mCursor.getColumnIndex(from[0])));
            holder.type.setText(mCursor.getString(mCursor.getColumnIndex(from[1])));
            holder.translate.setText(mCursor.getString(mCursor.getColumnIndex(from[2])));
            // holder.img.setImageResource(img_resource);

        }

        return convertView;
    }

}

在主要活动中,我将其称为:

adapter = new ListWordAdapter(getSherlockActivity(), R.layout.row_list_words, mCursorWords, from, to, 0);

当对列表进行修改时,我调用此方法:

public void onWordSaved() {
        WordDAO wordsDao = new WordSqliteDAO();
        Cursor mCursorWords = wordsDao.list(getSherlockActivity());
        adapter.changeCursor(mCursorWords);
    }

这里的事情是,这产生了我这个例外:

10-29 11:14:33.810: E/AndroidRuntime(18659): java.lang.IllegalStateException: 数据库/data/data/com.example.palabrasdeldia/databases/palabrasDelDia (conn# 0) 已经关闭

完整的堆栈跟踪:

10-29 11:14:33.810:E/AndroidRuntime(18659):致命异常:主要 10-29 11:14:33.810:E/AndroidRuntime(18659):java.lang.IllegalStateException:数据库/data/data/com。 example.palabrasdeldia/databases/palabrasDelDia (conn# 0) 已经关闭 10-29 11:14:33.810: E/AndroidRuntime(18659): at android.database.sqlite.SQLiteDatabase.verifyDbIsOpen(SQLiteDatabase.java:2123) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.database.sqlite.SQLiteDatabase.lock(SQLiteDatabase.java:398) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.database .sqlite.SQLiteDatabase.lock(SQLiteDatabase.java:390) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:74) 10-29 11 :14:33.810:E / AndroidRuntime(18659):在android.database.sqlite.SQLiteCursor。fillWindow(SQLiteCursor.java:311) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:283) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.database.AbstractCursor.moveToPosition(AbstractCursor.java:173) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 > com.example.palabrasdeldia.adapters.ListWordAdapter.getView(ListWordAdapter.java:42) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.widget.AbsListView.obtainView(AbsListView.java:2128) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android. widget.ListView.makeAndAddView(ListView.java:1817) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.widget.ListView.fillSpecific(ListView.java:1361) 10-29 11:14: 33.810: E/AndroidRuntime(18659): 在 android.widget.ListView.layoutChildren(ListView.java:1646) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.widget.AbsListView.onLayout(AbsListView .java:1979) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.view.View.layout(View.java:9593) 10-29 11:14:33.810: E/AndroidRuntime(18659 ): 在 android.view.ViewGroup.layout(ViewGroup.java:3877) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.widget.LinearLayout。setChildFrame(LinearLayout.java:1542) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.widget.LinearLayout.layoutHorizo​​ntal(LinearLayout.java:1527) 10-29 11:14:33.810: E/ AndroidRuntime(18659): 在 android.widget.LinearLayout.onLayout(LinearLayout.java:1316) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.view.View.layout(View.java:9593 ) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.view.ViewGroup.layout(ViewGroup.java:3877) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android .widget.FrameLayout.onLayout(FrameLayout.java:400) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.view.View.layout(View.java:9593) 10-29 11:14 :33.810: E/AndroidRuntime(18659): 在 android.view.ViewGroup.layout(ViewGroup.java:3877) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.support.v4。view.ViewPager.onLayout(ViewPager.java:1589) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.view.View.layout(View.java:9593) 10-29 11:14: 33.810: E/AndroidRuntime(18659): 在 android.view.ViewGroup.layout(ViewGroup.java:3877) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.widget.FrameLayout.onLayout(FrameLayout .java:400) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.view.View.layout(View.java:9593) 10-29 11:14:33.810: E/AndroidRuntime(18659 ): 在 android.view.ViewGroup.layout(ViewGroup.java:3877) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.widget.LinearLayout.setChildFrame(LinearLayout.java:1542) 10- 29 11:14:33.810: E/AndroidRuntime(18659): 在 android.widget.LinearLayout.layoutVertical(LinearLayout.java:1403) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.widget.LinearLayout.onLayout(LinearLayout.java:1314) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.view.View.layout(View.java:9593) 10-29 11:14: 33.810: E/AndroidRuntime(18659): 在 android.view.ViewGroup.layout(ViewGroup.java:3877) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.widget.FrameLayout.onLayout(FrameLayout .java:400) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.view.View.layout(View.java:9593) 10-29 11:14:33.810: E/AndroidRuntime(18659 ): 在 android.view.ViewGroup.layout(ViewGroup.java:3877) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.widget.LinearLayout.setChildFrame(LinearLayout.java:1542) 10- 29 11:14:33.810: E/AndroidRuntime(18659): 在 android.widget.LinearLayout.layoutVertical(LinearLayout.java:1403) 10-29 11:14:33.810: E/AndroidRuntime(18659):在 android.widget.LinearLayout.onLayout(LinearLayout.java:1314) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.view.View.layout(View.java:9593) 10-29 11 :14:33.810: E/AndroidRuntime(18659): 在 android.view.ViewGroup.layout(ViewGroup.java:3877) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.widget.FrameLayout。 onLayout(FrameLayout.java:400) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.view.View.layout(View.java:9593) 10-29 11:14:33.810: E/ AndroidRuntime(18659): 在 android.view.ViewGroup.layout(ViewGroup.java:3877) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.widget.FrameLayout.onLayout(FrameLayout.java:400 ) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.view.View.layout(View.java:9593) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android 。看法。ViewGroup.layout(ViewGroup.java:3877) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.view.ViewRoot.performTraversals(ViewRoot.java:1253) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.view.ViewRoot.handleMessage(ViewRoot.java:2017) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.os.Handler.dispatchMessage(Handler.java :99) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 android.os.Looper.loop(Looper.java:132) 10-29 11:14:33.810: E/AndroidRuntime(18659):在 android.app.ActivityThread.main(ActivityThread.java:4028) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 java.lang.reflect.Method.invokeNative(Native Method) 10-29 11: 14:33.810: E/AndroidRuntime(18659): 在 java.lang.reflect.Method.invoke(Method.java:491) 10-29 11:14:33.810: E/AndroidRuntime(18659): 在 com.android。internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844) 10-29 11:14:33.810: E/AndroidRuntime(18659): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602 ) 10-29 11:14:33.810: E/AndroidRuntime(18659): at dalvik.system.NativeStart.main(Native Method)

如果我直接使用 SimpleCursorAdapter 而不是 ListWordAdapter,它可以正常工作。我的自定义适配器实现有什么问题?堆栈跟踪中的粗体行对应于:getView 方法中的 if (mCursor.moveToPosition(position))。

编辑

我创建了一个自定义类来管理打开和关闭的数据库操作:

public class ConexionBD {
    private Context context;
    private SQLiteDatabase database;
    private DataBaseHelper dbHelper;

    public ConexionBD(Context context) {
        this.context = context;
    }

    public ConexionBD open() throws SQLException {
        this.dbHelper = DataBaseHelper.getInstance(context);
        this.database = dbHelper.getWritableDatabase();
        database.execSQL("PRAGMA foreign_keys=ON");
        return this;
    }

    public void close() {
        if (database.isOpen() && database != null) {
            dbHelper.close();
        }
    }

    /*Getters y setters*/
    public SQLiteDatabase getDatabase() {
        return database;
    }

    public void setDatabase(SQLiteDatabase database) {
        this.database = database;
    }

}

这是我的DataBaseHelper:

公共类 DataBaseHelper 扩展 SQLiteOpenHelper {

private static final String DATABASE_NAME = "myDb";
private static final int DATABASE_VERSION = 1;
private static DataBaseHelper sInstance = null;


public static DataBaseHelper getInstance(Context context) {

    // Use the application context, which will ensure that you
    // don't accidentally leak an Activity's context.
    // See this article for more information: http://bit.ly/6LRzfx
    if (sInstance == null) {
        sInstance = new DataBaseHelper(context.getApplicationContext());
    }
    return sInstance;
}

@Override
public void onCreate(SQLiteDatabase database) {
    ...
}
 ....

这是我如何管理查询的示例:

public Cursor list(Context context) {
        ConexionBD conexion = new ConexionBD(context);
        Cursor mCursor = null;
        try{
            conexion.open();

            mCursor = conexion.getDatabase().query(DataBaseHelper.TABLE_WORD , null , null, null, null, null, Word.NAME);

            if (mCursor != null) {
                mCursor.moveToFirst();
            }

        }finally{
            conexion.close();
        }

        return mCursor; 
    }

对于与数据库的每个连接,我都会打开它并关闭它。

4

1 回答 1

0

我发现了问题!这是getView方法,特别是提到的错误这一行:

if (mCursor.moveToPosition(position))

我不应该使用构造函数的光标,而是必须从该位置获取一个新光标:

Cursor cursor = (Cursor) getItem(position);

这样我就不会尝试访问数据库已经关闭的游标。我发布的所有代码都是正确的,唯一的就是我在 getView 方法中使用的光标。

于 2013-10-31T13:44:13.683 回答