我的应用程序运行正常,直到我偶然发现了这个SQLite错误:
java.lang.IllegalMoniterStateException: attempt to unlock read lock, not locked by current thread
我已经在StackOverflow上尝试了所有其他答案,但它们似乎没有帮助。他们都说我有多个线程创建我的SQLiteDBAdpdter的实例,但我只有Activity,但它只有SherlockFragmentActivity。每个类都创建一个SQliteDBAdapter的新实例,所以我不确定这是否是我收到此错误的原因。
我被困在这几个小时,并且 GREATLY 感谢任何帮助。
片段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;
}
我的NotesDBAdapter中的onCreate()
是:
@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相同。
答案 0 :(得分:1)
我不确定这是不是问题,但似乎你要为写入打开两次相同的数据库。请打开一个并在您的应用程序中共享它。
答案 1 :(得分:1)
你写道:
每个类都创建一个SQliteDBAdapter的新实例,所以 我不确定这是否是我收到此错误的原因。
我不确定你在哪个课程,因为我在你的例子中只看到两个部分课程 - NotesFragment
和NotesDbAdapter
。但是,如果您的活动依赖于每个打开和关闭数据库的其他类,那么您必须确保没有任何递归尝试打开数据库。 (即,A类打开数据库,然后调用B类,它尝试使用自己的DBHelper实例打开数据库。此时,B正在尝试打开数据库,而A打开它。)
正如前面提到的dongshengcn,这可能是错误。在NotesFragment.onCreate
中打开数据库并在NotesFragment.onDestroy
中关闭它,并将db
对象从NotesFragment
传递到其他类中可能更合适。
接下来的问题是,您的NotesDbAdapter
班级是否有适当的close
方法?它应该看起来像这样,并且(如上所述)从NotesFragment.onDestroy
调用。
@Override
public synchronized void close() {
if (mDbHelper != null) {
mDbHelper.close();
mDbHelper = null;
}
super.close();
}