2011-03-09 23 views
0

我建立與具有下面的代碼的活動Android應用程序:如何解決「請確保您明確地在您的光標上調用close()」?

public class SavedSalesActivity extends Activity { 

    protected ListView mSalesList; 
    protected Cursor mSalesCursor; 
    protected SalesCursorAdapter mSalesAdapter; 
    protected SalesDbAdapter mDb; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.sales_list); 

     mDb = new SalesDbAdapter(this); 
     mDb.open(); 
     mSalesCursor = mDb.getSaved(); 
     startManagingCursor(mSalesCursor); 

     mSalesAdapter = new SalesCursorAdapter(this, R.layout.sales_list_item, mSalesCursor, 
       new String[0], new int[0]); 

     mSalesList = (ListView)findViewById(R.id.sales_listview); 
     mSalesList.setAdapter(mSalesAdapter); 
     mSalesList.setEmptyView(findViewById(android.R.id.empty)); 
     mSalesList.setOnItemClickListener(new OnItemClickListener() {...}); 
    } 

    @Override 
    protected void onStart() { 
     Log.v(TAG, "Starting SavedSalesActivity"); 

     mDb.open(); 

     mSalesCursor = mDb.getSaved(); 
     startManagingCursor(mSalesCursor); 

     super.onStart(); 
    } 

    @Override 
    protected void onStop() { 
     Log.v(TAG, "Stopping SavedSalesActivity"); 

     mSalesCursor.close(); 

     mDb.close(); 

     super.onStop(); 
    } 
} 

按照我的理解,這應該是綽綽有餘正確關閉我所有的資源更多,但是如果我打開這個活動並退出它與Android設備後退按鈕,我在短暫(可變)的一段時間後在Logcat中得到這個。

03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169): Releasing statement in a finalizer. Please ensure that you explicitly call close() on your cursor: SELECT * FROM sales ORDER BY featured DESC 
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here 
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):  at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:62) 
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):  at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:80) 
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):  at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:46) 
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):  at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:42) 
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):  at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1345) 
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):  at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1229) 
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):  at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1184) 
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):  at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1264) 
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):  at com.maps.app.classifiedconcepts.sale.SalesDbAdapter.getSaved(SalesDbAdapter.java:149) 
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):  at com.maps.app.classifiedconcepts.sale.SavedSalesActivity.onCreate(SavedSalesActivity.java:113) 
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) 
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):  at android.app.ActivityThread.access$2300(ActivityThread.java:125) 
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033) 
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):  at android.os.Handler.dispatchMessage(Handler.java:99) 
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):  at android.os.Looper.loop(Looper.java:123) 
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):  at android.app.ActivityThread.main(ActivityThread.java:4627) 
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):  at java.lang.reflect.Method.invokeNative(Native Method) 
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):  at java.lang.reflect.Method.invoke(Method.java:521) 
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
03-08 19:33:58.492: WARN/SQLiteCompiledSql(5169):  at dalvik.system.NativeStart.main(Native Method) 
03-08 19:33:58.503: ERROR/Database(5169): close() was never explicitly called on database '/data/data/com.maps.app.classifiedconcepts/databases/classified_concepts' 
03-08 19:33:58.503: ERROR/Database(5169): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here 
03-08 19:33:58.503: ERROR/Database(5169):  at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1810) 
03-08 19:33:58.503: ERROR/Database(5169):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:817) 
03-08 19:33:58.503: ERROR/Database(5169):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:851) 
03-08 19:33:58.503: ERROR/Database(5169):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:844) 
03-08 19:33:58.503: ERROR/Database(5169):  at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:540) 
03-08 19:33:58.503: ERROR/Database(5169):  at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203) 
03-08 19:33:58.503: ERROR/Database(5169):  at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:112) 
03-08 19:33:58.503: ERROR/Database(5169):  at com.maps.app.classifiedconcepts.sale.SalesDbAdapter.open(SalesDbAdapter.java:163) 
03-08 19:33:58.503: ERROR/Database(5169):  at com.maps.app.classifiedconcepts.sale.SavedSalesActivity.onCreate(SavedSalesActivity.java:112) 
03-08 19:33:58.503: ERROR/Database(5169):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
03-08 19:33:58.503: ERROR/Database(5169):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) 
03-08 19:33:58.503: ERROR/Database(5169):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 
03-08 19:33:58.503: ERROR/Database(5169):  at android.app.ActivityThread.access$2300(ActivityThread.java:125) 
03-08 19:33:58.503: ERROR/Database(5169):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033) 
03-08 19:33:58.503: ERROR/Database(5169):  at android.os.Handler.dispatchMessage(Handler.java:99) 
03-08 19:33:58.503: ERROR/Database(5169):  at android.os.Looper.loop(Looper.java:123) 
03-08 19:33:58.503: ERROR/Database(5169):  at android.app.ActivityThread.main(ActivityThread.java:4627) 
03-08 19:33:58.503: ERROR/Database(5169):  at java.lang.reflect.Method.invokeNative(Native Method) 
03-08 19:33:58.503: ERROR/Database(5169):  at java.lang.reflect.Method.invoke(Method.java:521) 
03-08 19:33:58.503: ERROR/Database(5169):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
03-08 19:33:58.503: ERROR/Database(5169):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
03-08 19:33:58.503: ERROR/Database(5169):  at dalvik.system.NativeStart.main(Native Method) 

mSalesCursor = mDb.getSaved();調用我SalesDbAdapter下面的代碼:

public Cursor getSaved() { 
return mDb.query(TABLE_NAME, null, null, null, null, null, KEY_FEATURED + " DESC"); 
} 

我在做什麼錯?爲什麼我會收到這些例外情況?我特別困惑,因爲我認爲在初始化mSalesCursor後立即調用startManagingCursor(mSalesCursor)可以節省我在任何Activity生命週期方法中關閉Cursor的需求。

+0

爲什麼你獲得兩個遊標?一個在onCreate和另一個在onStart?什麼是這兩個行號:com.maps.app.classifiedconcepts.sale.SalesDbAdapter.getSaved(SalesDbAdapter.java:149) com.maps.app.classifiedconcepts.sale.SavedSalesActivity.onCreate(SavedSalesActivity.java:113) – bhups 2011-03-09 04:05:54

+0

我原來的代碼沒有在onStart()中獲得遊標,但我添加了它,因爲在排除故障時,我添加了mSalesCursor.close();到onStop()。 – rushinge 2011-03-09 04:11:45

+0

編輯原帖顯示SalesDbAdapter.java:149和SavedSalesActivity.java:113 – rushinge 2011-03-09 04:28:23

回答

0

對於這類事情,您應該覆蓋onResume()onPause()而不是onStart()onStop()。查看Activity Lifecycle文檔。

+0

這讓我在正確的道路上,我最終能夠解決它,所以你的功勞。 – rushinge 2011-03-15 03:03:41

0

考慮調用startManagingCursor()

+0

原來的onCreate()代碼調用startManagingCursor()與** mSalesCursor = mDb.getSaved()對其進行初始化後立即**我認爲這是我不得不做的,讓光標停留周圍,但它似乎沒有上班。 – rushinge 2011-03-09 04:30:39

2

對於其他人在看這個答案,我總是纏上了我用的try/catch/finally語句遊標的使用。這提供了確定性,無論發生什麼,光標都會關閉。

我用這個經常說我還送一個Eclipse模板。

例如:

void foo() { 
    Cursor c = null; 
    try { 
     c = db.get_somthing(); 
     do_something©; 
    }  

    catch (Exception e) { 
     print_err_msg(e); 
    } 

    finally { 
     if (c != null) { 
      c.close(); 
      c = null; 
     } 
    } 
} 
相關問題