Как я понимаю, лоадер пытается получить уже несуществующий курсор. Но беда в том, что ошибка проявляется нерегулярно. Может вылететь почти сразу, а может и нет. Ошибка проявляется при переходе из одного фрагмента в другой. Вот реализация лоадера:java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteQuery: SELECT _id, name FROM company GROUP BY name
Код: Выделить всё
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle bndl) {
return new MainCursorLoader(this);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
adapter.swapCursor(cursor);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
adapter.swapCursor(null);
}
static class MainCursorLoader extends CursorLoader {
public MainCursorLoader(Context context) {
super(context);
}
@Override
public Cursor loadInBackground() {
try {
switch (category) {
case 0:
return dbHelper.getAllCursor();
case 1:
return dbHelper.getCompanyList();
case 4:
return dbHelper.getFavorite();
default:
return null;
}
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
}
Вот код класса DBHelper:
Код: Выделить всё
// Класс для работы с БД
public class DBHelper extends SQLiteOpenHelper{
private AtomicInteger mOpenCounter = new AtomicInteger();
private static DBHelper mInstance;
private SQLiteDatabase mDatabase;
private static Context context;
private DBHelper(Context _context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(_context, name, factory, version);
context = _context;
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i2) {
}
public static synchronized void initializeInstance (Context _context, String name, SQLiteDatabase.CursorFactory factory, int version) {
if (mInstance == null) {
mInstance = new DBHelper(_context.getApplicationContext(), name, factory, version);
context = _context;
}
}
public static synchronized DBHelper getInstance() {
if (mInstance == null) {
throw new IllegalStateException(DBHelper.class.getSimpleName() +
" is not initialized, call initializeInstance(..) method first.");
}
return mInstance;
}
public synchronized SQLiteDatabase openDataBase() {
if(mOpenCounter.incrementAndGet() == 1) {
// Opening new database
File DB_PATH = context.getExternalFilesDir(null);
File dbFile = new File(DB_PATH, DataBase.DB_NAME);
//if (!mDatabase.isOpen())
mDatabase = context.openOrCreateDatabase(dbFile.getAbsolutePath(), SQLiteDatabase.OPEN_READWRITE, null);
}
return mDatabase;
}
public synchronized void closeDataBase() {
if(mOpenCounter.decrementAndGet() == 0) {
// Closing database
mDatabase.close();
}
}
public Cursor getAllCursor() throws SQLException {
SQLiteDatabase database = DBHelper.getInstance().openDataBase();
Cursor cursor = database.query(DataBase.ProductList.TABLE_NAME, new String[] { DataBase.ProductList.COLUMN_ID,
DataBase.ProductList.COLUMN_RUS_NAME, DataBase.ProductList.COLUMN_ZIP },
null, null, DataBase.ProductList.COLUMN_RUS_NAME, null, null);
//DBHelper.getInstance().closeDataBase();
return cursor;
}
public Cursor getFavorite() throws SQLException {
SQLiteDatabase database = DBHelper.getInstance().openDataBase();
Cursor cursor = database.query(DataBase.ProductList.TABLE_NAME, new String[] { DataBase.ProductList.COLUMN_ID,
DataBase.ProductList.COLUMN_RUS_NAME, DataBase.ProductList.COLUMN_ZIP },
DataBase.ProductList.COLUMN_FAVORITE + " = 1", null,
DataBase.ProductList.COLUMN_RUS_NAME, null, null);
//DBHelper.getInstance().closeDataBase();
return cursor;
}
public Cursor getCompanyList() throws SQLException {
SQLiteDatabase database = DBHelper.getInstance().openDataBase();
Cursor cursor = database.query(DataBase.Company.TABLE_NAME, new String[] { DataBase.Company.COLUMN_ID, DataBase.Company.COLUMN_NAME },
null, null, DataBase.Company.COLUMN_NAME, null, null);
//DBHelper.getInstance().closeDataBase();
return cursor;
}
}
Код: Выделить всё
getLoaderManager().restartLoader(0, null, this);
Код: Выделить всё
fragmentManager.beginTransaction()
.add(R.id.content_frame, fragment).addToBackStack(null).commit();
fragmentManager.beginTransaction()
.hide(thisFragment).commit();
Потом, когда возвращаюсь назад, или вызываю другой фрагмент, делаю в методе onDestroy следующее:
Код: Выделить всё
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.show(getFragmentManager().findFragmentById(parent_id)).commit();
Я сделал так, чтобы при возврате на предыдущий фрагмент, ListView оставался на прежней позиции, а не сбрасывался на начало списка. Вот лог ошибки:
Код: Выделить всё
java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteQuery: SELECT _id, name FROM company GROUP BY name
at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:58)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:152)
at android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:124)
at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:214)
at android.widget.CursorAdapter.getItemId(CursorAdapter.java:223)
at android.widget.AbsListView.onSaveInstanceState(AbsListView.java:1764)
at android.view.View.dispatchSaveInstanceState(View.java:12728)
at android.view.ViewGroup.dispatchFreezeSelfOnly(ViewGroup.java:2629)
at android.widget.AdapterView.dispatchSaveInstanceState(AdapterView.java:783)
at android.view.ViewGroup.dispatchSaveInstanceState(ViewGroup.java:2615)
at android.view.View.saveHierarchyState(View.java:12711)
at android.app.FragmentManagerImpl.saveFragmentViewState(FragmentManager.java:1577)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:951)
at android.app.FragmentManagerImpl.removeFragment(FragmentManager.java:1167)
at android.app.BackStackRecord.run(BackStackRecord.java:641)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1447)
at android.app.FragmentManagerImpl$1.run(FragmentManager.java:443)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
at dalvik.system.NativeStart.main(Native Method)