0

My application was running fine, until I stumbled across this SQLite error:

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

I've tried all the other answers on StackOverflow, but they didn't seem to help. They all said I have multiple threads creating instances of my SQLiteDBAdpdter, but I only have on Activity, but its a SherlockFragmentActivity. Each of the classes create a new instance of the SQliteDBAdapter, so I'm not sure if this is why I'm getting this error.

I've been stuck on this for hours, and would GREATLY appreciate any help.

Fragment 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;

}

}

The error is pointing to db.open(); in the onCreate() method. The open() method is in my SQLiteDBAdapter (NotesDBAdapter) which is as follows:

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

And theonCreate() in my NotesDBAdapter is:

@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);

        } 

    }

Thanks again!

EDIT The other fragment

creating a new instance

of the database is called fragment 2, but I did not show its code as its really the same as fragment 1.

Buneme Kyakilika
  • 1,202
  • 3
  • 13
  • 34

2 Answers2

1

I am not sure if this is the problem, but seems you are opening the same database twice for write. Please just open one and share it within your application.

Please also read here: Android threading and database locking

Community
  • 1
  • 1
dongshengcn
  • 6,434
  • 7
  • 35
  • 44
1

You write:

Each of the classes create a new instance of the SQliteDBAdapter, so I'm not sure if this is why I'm getting this error.

I'm not sure which classes you mean there, since I only see two partial classes in your example -- NotesFragment and NotesDbAdapter. But if your activity depends on other classes that each open and close the database, then you must ensure that there aren't any recursive attempts to open the DB. (I.e., class A opens the database, then calls class B, which attempts to open the database using its own instance of the DBHelper. At that point, B is trying to open the database while A has it open.)

As dongshengcn noted earlier, that could be the bug. It might be more appropriate to open the database in NotesFragment.onCreate, and close it in NotesFragment.onDestroy, and pass the db object from NotesFragment into these other classes.

The next question is, does your NotesDbAdapter class have an appropriate close method? It should look something like this, and (as mentioned above) be called from NotesFragment.onDestroy.

    @Override
    public synchronized void close() {

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

        super.close();
    }
Community
  • 1
  • 1
Dan Breslau
  • 11,472
  • 2
  • 35
  • 44
  • I've edited my question, thanks **but my app force closes as soon as its opened** – Buneme Kyakilika Apr 15 '13 at 18:34
  • 1
    You mean, it was FCing on open even before any changes suggested here, right? That doesn't rule out the suggestions you've gotten here. It would help to see the stack trace. You might also try setting a breakpoint in onCreate() and stepping through the code from there. – Dan Breslau Apr 15 '13 at 18:42