5

Tôi đang bối rối về những gì gây ra lỗi này, vì tôi đã đảm bảo rằng tôi đóng bộ điều hợp cơ sở dữ liệu đúng cách (ít nhất là tôi nghĩ). Đây là những gì nói LogCat của (thẻ cho tất cả trong số họ là AndroidRuntime):IllegalStateException: cơ sở dữ liệu đã bị đóng (sử dụng ViewPager)

EXCEPTION Fatal: chính java.lang.IllegalStateException: cơ sở dữ liệu /data/data/com.acedit.assignamo/databases/data.db (conn # 0) đã đóng tại android.database.sqlite.SQLiteDatabase.verifyDbIsOpen (SQLiteDatabase.java:2082) tại android.database.sqlite.SQLiteDatabase.lock (SQLiteDatabase.java:413) tại android.database.sqlite. SQLiteDatabase.lock (SQLiteDatabase.java:400) tại android.database.sqlite.SQLiteQuery.fillWindow (SQLiteQuery.java:79) tại android.database.sqlite.SQLiteCursor.fillWindow (SQLiteCursor.java:164) tại và roid.database.sqlite.SQLiteCursor.onMove (SQLiteCursor.java:147) tại android.database.AbstractCursor.moveToPosition (AbstractCursor.java:178) tại android.support.v4.widget.CursorAdapter.getItemId (CursorAdapter.java: 225) tại android.widget.AbsListView.onSaveInstanceState (AbsListView.java:1569) tại android.view.View.dispatchSaveInstanceState (View.java:9868) tại android.view.ViewGroup.dispatchFreezeSelfOnly (ViewGroup.java:2310) tại android.widget.AdapterView.dispatchSaveInstanceState (AdapterView.java:770) tại android.view.ViewGroup.dispatchSaveInstanceState (ViewGroup.java:2296) tại android.view.View.saveHierarchyState (View.java:9851) at android.support.v4.app.FragmentManagerImpl.saveFragmentViewState (Fragme ntManager.java:1561) tại android.support.v4.app.FragmentManagerImpl.moveToState (FragmentManager.java:962) tại android.support.v4.app.FragmentManagerImpl.detachFragment (FragmentManager.java:1233) tại android. support.v4.app.BackStackRecord.run (BackStackRecord.java:620) tại android.support.v4.app.FragmentManagerImpl.execPendingActions (FragmentManager.java:1431) tại android.support.v4.app.FragmentManagerImpl.executePendingTransactions (FragmentManager.java:431) tại android.support.v4.app.FragmentPagerAdapter.finishUpdate (FragmentPagerAdapter.java:141) tại android.support.v4.view.ViewPager.populate (ViewPager.java:895) tại android. support.v4.view.ViewPager.populate (ViewPager.java:772) tại android.support.v4.vi ew.ViewPager.completeScroll (ViewPager.java:1539) tại android.support.v4.view.ViewPager.computeScroll (ViewPager.java:1422) tại android.view.View.getDisplayList (View.java:10406) tại android.view.ViewGroup.dispatchGetDisplayList (ViewGroup.java:2597) tại android.view.View.getDisplayList (View.java:10380) tại android.view.ViewGroup.dispatchGetDisplayList (ViewGroup.java:2597) tại android. view.View.getDisplayList (View.java:10380) tại android.view.ViewGroup.dispatchGetDisplayList (ViewGroup.java:2597) tại android.view.View.getDisplayList (View.java:10380) tại android.view. ViewGroup.dispatchGetDisplayList (ViewGroup.java:2597) tại android.view.View.getDisplayList (View.java:10380) tại android.view.HardwareRenderer $ GlRenderer.draw (HardwareRenderer.java:875) tại android.view.ViewRootImpl.draw (ViewRootImpl.java:1910) tại android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:1634) tại android.view.ViewRootImpl.handleMessage (ViewRootImpl.java:2442) tại android.os.Handler.dispatchMessage (Handler.java:99) tại android.os.Looper.loop (Looper.java:137) tại android.app.ActivityThread.main (ActivityThread.java:4575) tại java.lang.reflect.Method.invokeNative (Native Method) tại java.lang.reflect.Method.invoke (Method.java WEBC11) tại com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:786) at com .android.internal.os.ZygoteInit.main (ZygoteInit.java:553) tại dalvik.system.NativeStart.main (Native Method)

mã của tôi:

public Cursor fetchIncompleteAssignments(Short course) { 
    DbAdapter adapter = new DbAdapter(context, null, Values.ASSIGNMENT_TABLE); 
    adapter.open(); 

    Cursor r; 
    if (course == null) // Fetching from all courses 
     r = adapter.fetchAllWhere(Values.ASSIGNMENT_LIST_FETCH, Values.ASSIGNMENT_KEY_STATUS + "=" + 0, Values.ASSIGNMENT_KEY_DUE_DATE); 
    else 
     r = adapter.fetchAllWhere(Values.ASSIGNMENT_LIST_FETCH, Values.ASSIGNMENT_KEY_COURSE + "=" + course 
      + " AND " + Values.ASSIGNMENT_KEY_STATUS + "=" + 0, Values.ASSIGNMENT_KEY_DUE_DATE); 
    adapter.close(); 
    return r; 
} 

// Part of DbAdapter: 
public DbAdapter open() throws SQLException { 
    dbHelper = new DatabaseHelper(context); 
    db = dbHelper.getWritableDatabase(); 
    return this; 
} 

public void close() { 
    if (db != null) { 
     try { 
      db.close(); 
      dbHelper.close(); 
     } catch (NullPointerException e) { 
      Log.e("Close", "Error: " + e + " " + e.getMessage()); 
     } 
    } else 
     Log.e("Close", "Error! db \"" + DATABASE_TABLE + "\" is null."); 
} 

Các Cursor trở về từ fetchAllAssignments() được sử dụng để điền ListView thông qua tùy chỉnh CursorAdapter. ListView là nội dung của ListFragment và có nhiều phiên bản của ListFragment này được hiển thị trong mỗi trang của ViewPager (một cho hiển thị các bài tập từ tất cả các khóa học và sau đó là một trang cho từng khóa học riêng lẻ).

Bất kỳ ý tưởng nào về điều gì sai? Theo tôi biết, tôi sẽ đóng đúng cơ sở dữ liệu của mình. Hãy cho tôi biết nếu bạn cần thêm mã. Cảm ơn trước!

CHỈNH SỬA: Dữ liệu được lấy từ cơ sở dữ liệu và cũng điền vào ListView. Tôi có thể vuốt qua các trang khác nhau, nhưng dường như nó sụp đổ bất cứ khi nào Fragment bị dừng lại. Nó thường sẽ sụp đổ khi tôi bắt đầu Hoạt động khác, nhưng không phải lúc nào cũng vậy. Nó cũng sẽ thỉnh thoảng sụp đổ khi tôi lướt qua các trang, mặc dù rất hiếm khi. Dưới đây là phương pháp của tôi onPause() cho Fragment của tôi (tôi không có một onStop() hoặc onDestroy()):

public void onPause() { 
    super.onPause(); 
    if (!assignmentsCursor.isClosed()) { 
     assignmentsCursor.close(); 
     assignmentsCursor = null; 
    } 
} 

Trong tôi onResume() Tôi chỉ cần tải lại danh sách từ cơ sở dữ liệu và nhận được một bản sao mới của ngữ cảnh qua getActivity(). Có lẽ một cái gì đó là nhận được xóa (cho mục đích bộ nhớ) và tôi không tải lại nó? Tôi không nhận được bất kỳ loại NullPointerException, do đó, điều này dường như không cho tôi ...

Trả lời

3

ngoại lệ này thực sự được nâng lên vì bạn đã đóng đôi cơ sở dữ liệu của mình chứ không phải vì bạn không đóng nó.

vì vậy ..

trong bạn close() phương pháp, thay thế các dòng sau trong mã của bạn:

if (db != null) { 

với:

if (db != null && db.isOpen()) { 
+0

Vâng, điều đó chắc chắn làm cho ý nghĩa nhất của tất cả các câu trả lời. Tôi chưa bao giờ nghĩ đến điều đó. :) – mightimaus

+0

cảm ơn @ EverythingTech96, nếu điều này giải quyết được vấn đề của bạn, hãy cho tôi biết. – kdehairy

2

Làm cho DbHelper một singleton của bạn, như được mô tả trong this post.

+0

Tôi nghĩ rằng giúp đỡ. Nó vẫn thỉnh thoảng bị treo, nhưng tôi nghĩ ít hơn nhiều. Lời khuyên tốt anyway, cảm ơn! :) Bất kỳ ý tưởng nào khác? – mightimaus

+0

Nếu bạn đã tạo một đĩa đơn 'DbHelper', bạn không cần phải đóng nó lại. –

+0

Tôi có cần phải đóng 'SQLiteDatabase' (' db') của mình không? – mightimaus

Các vấn đề liên quan