2013-03-29 18 views
2

我在這裏看到很多關於它的帖子,但我只是不能讓我的應用程序停止發送我關於我沒有關閉數據庫的錯誤。我的數據庫有時通過活動訪問,有時來自後臺類(服務)。何時關閉數據庫至關重要?

我添加到活動中的使用DB

protected void onDestroy() { 
    Log.d("OnDestroy", "called"); 
    sqlAdapter helper = new sqlAdapter(StartScreen.this); 
    helper.close(); 
    super.onDestroy(); 
} 

這裏建議在很多職位,但它不會解決問題。

有什麼想法或解釋來幫助我理解?應用程序不會崩潰或什麼,但很多關於我的錯誤不關閉DB

謝謝!

+1

始終釋放您已聲明? – hd1

回答

0

在你的例子中,看起來你是在onDestroy中創建一個新對象而不是關閉舊對象。所以每次你做

sqlAdapter helper = new sqlAdapter(StartScreen.this); 

您正在創建一個新的對象,你就會有一噸未閉合的引用,這是什麼原因造成的警告。

相反,它看起來像你可能會尋找一個單一的設計模式,這將允許你在應用程序中維護一個對象,然後關閉它在onDestroy

public void onDestroy() { 
    super.onDestroy(); 
    // close database 
    final MySqlHelper helper = MySqlHelper.getInstance(); 
    helper.getDatabase().close(); 
} 

否則,它仍然是開放的,直到onDestroy,就像你現在要做的一樣。這當然應該在適當的時候使用,並且你正在你的應用程序中積極使用它。如果你很少使用數據庫,你可以在每次使用後關閉它。

的想法是,你減少數據庫/接近電話,如果你做他們適量,將在該用例更有效率。

這是一個非常非常簡單的單例例子。

public class MySqlHelper extends SQLiteOpenHelper { 
    static MySqlHelper mInstance = null; 
    static SQLiteDatabase mDatabase = null; 

    public static MySqlHelper getInstance() { 
     if (mInstance == null) { 
      // call private constructor 
      mInstance = new MySqlHelper(); 
     } 
     mDatabase = mInstance.getWritableDatabase(); 
     while(mDatabase.isDbLockedByCurrentThread() || mDatabase.isDbLockedByOtherThreads()) { 
      // loop until available 
     } 
     return mInstance; 
    } 

    private MySqlHelper() { 
     // mContext here is just a placeholder for your ApplicationContext 
     // that you should have available to this class. 
     super(mContext, DATABASE_NAME, null, DATABASE_VERSION); 
    } 

    // all other filled out methods like onCreate, onUpgrade, etc 
} 

現在你可以用它來實現你的數據源

public class MyDataSource { 
    // Database fields 
    private final SQLiteDatabase mDatabase; 
    private final MySqlHelper mHelper; 

    public MyDataSource() { 
     mHelper = MySqlHelper.getInstance(); 
     mDatabase = mHelper.getDatabase(); 
    } 

    // add your custom methods 

    private int update(ContentValues values, String whereClause) { 
     int rowsUpdated = 0; 
     synchronized (mDatabase) { 
      rowsUpdated = mDatabase.update(MySqlHelper.TABLE_NAME, values, whereClause, null); 
     } 
     return rowsUpdated; 
    } 

    public int updateById(ContentValues values, int id) { 
     final String whereClause = MySqlHelper.COLUMN_ID + "=" + id; 
     return this.update(values, whereClause); 
    } 
} 
+0

完美完美!謝謝! –

0

您應該在每次完成後關閉它。如果您創建一個cursor來訪問它,那麼在獲取數據並保存或完成處理之後,您應該關閉cursor。然後在下次需要時再打開它。 This answer應該可以幫到你

+0

我只想指出,在使用連接池的情況下,這不一定是正確的。在這種情況下,我認爲情況並非如此,但在使用連接池時關閉連接會破壞使用連接池的目的。 – CodeChimp