0

我的应用程序运行良好,直到我偶然发现这个 SQLite 错误:

java.lang.IllegalMoniterStateException: attempt to unlock read lock, not locked by current thread

我已经尝试过 StackOverflow 上的所有其他答案,但它们似乎没有帮助。他们都说我有多个线程创建我的 SQLiteDBAdpdter 实例,但我只有 Activity,但它是一个 SherlockFragmentActivity。每个类都创建了一个新的 SQliteDBAdapter 实例,所以我不确定这是否是我收到此错误的原因。

我已经坚持了几个小时,非常感谢任何帮助。

片段 1:

public final class NotesFragment extends SherlockListFragment {
NotesDbAdapter db;
private static final int ACTIVITY_EDIT = 1;

private static final int DELETE_ID = Menu.FIRST + 1;

public static NotesFragment newInstance(String content) {
    NotesFragment fragment = new NotesFragment();

    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    db = new NotesDbAdapter(getActivity());

    db.open();
    if (db.fetchAllNotes().getCount() == 0) {
        doWelcomeMessage();
    }
    db.close();

}

private void doWelcomeMessage() {
    // Show welcome dialog
    startActivity(new Intent(getActivity(), NotesWelcome.class));

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    if (container == null) {
        return null;
    }

    db = new NotesDbAdapter(getActivity());

    db.open();
    if (db.fetchAllNotes().getCount() == 0) {
        doWelcomeMessage();
    }
    db.close();


    return ll;

}

}

错误指向方法db.open();onCreate()。我的open()方法SQLiteDBAdapter (NotesDBAdapter)如下:

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

onCreate()我的 NotesDBAdapter 中是:

@Override
    public void onCreate(SQLiteDatabase db) {

        SQLiteDatabase checkDB = null;

        String myPath = "data/data/com.xxx.xxx/databases/data.db";
        checkDB = SQLiteDatabase.openDatabase(myPath, null,
                SQLiteDatabase.OPEN_READONLY);
        if (checkDB != null) {
            // exists; do nothing
        } else {
            // create DB

            db.execSQL(DATABASE_CREATE);

        } 

    }

再次感谢!

编辑 另一个片段

创建一个新实例

数据库的代码称为片段 2,但我没有显示它的代码,因为它与片段 1 完全相同。

4

2 回答 2

1

你写:

每个类都创建了一个新的 SQliteDBAdapter 实例,所以我不确定这是否是我收到此错误的原因。

我不确定您指的是哪些类,因为在您的示例中我只看到两个部分类 -NotesFragmentNotesDbAdapter. 但是,如果您的活动依赖于每个打开和关闭数据库的其他类,那么您必须确保没有任何递归尝试打开数据库。(即,A 类打开数据库,然后调用 B 类,它尝试使用自己的 DBHelper 实例打开数据库。此时,B 试图打开数据库,而 A 已打开它。)

正如dongshengcn之前指出的那样,这可能是错误。NotesFragment.onCreate在 中打开数据库并在中关闭数据库并将对象从NotesFragment.onDestroy传递到这些其他类可能更合适。dbNotesFragment

下一个问题是,你的NotesDbAdapter班级有合适的close方法吗?它应该看起来像这样,并且(如上所述)从NotesFragment.onDestroy.

    @Override
    public synchronized void close() {

        if (mDbHelper != null) {
            mDbHelper.close();
            mDbHelper = null;
        }

        super.close();
    }
于 2013-04-15T17:00:00.630 回答
1

我不确定这是否是问题所在,但似乎您打开同一个数据库两次进行写入。请打开一个并在您的应用程序中共享它。

另请在此处阅读:Android 线程和数据库锁定

于 2013-04-15T15:16:27.043 回答